From 377561865aabf34d3bb242ad2fb112814a819e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 27 Dec 2016 15:52:03 +0100 Subject: [PATCH] A little more D3D11, BlendFactor --- UI/NativeApp.cpp | 2 +- ext/native/thin3d/thin3d.h | 3 +- ext/native/thin3d/thin3d_d3d11.cpp | 146 +++++++++++++++++++++++++++- ext/native/thin3d/thin3d_d3d9.cpp | 11 ++- ext/native/thin3d/thin3d_gl.cpp | 6 +- ext/native/thin3d/thin3d_vulkan.cpp | 7 +- 6 files changed, 168 insertions(+), 7 deletions(-) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 148d384a09..5f698798e6 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -621,7 +621,7 @@ void NativeInitGraphics(GraphicsContext *graphicsContext) { uiContext->Init(thin3d, texColorPipeline, colorPipeline, uiTexture, &ui_draw2d, &ui_draw2d_front); RasterStateDesc desc; desc.cull = CullMode::NONE; - desc.facing = Facing::CCW; + desc.frontFace = Facing::CCW; if (uiContext->Text()) uiContext->Text()->SetFont("Tahoma", 20, 0); diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 56891b256d..eee7483cfc 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -451,7 +451,7 @@ struct SamplerStateDesc { struct RasterStateDesc { CullMode cull; - Facing facing; + Facing frontFace; }; struct PipelineDesc { @@ -510,6 +510,7 @@ public: // Dynamic state virtual void SetScissorRect(int left, int top, int width, int height) = 0; virtual void SetViewports(int count, Viewport *viewports) = 0; + virtual void SetBlendFactor(float color[4]) = 0; virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0; virtual void BindTextures(int start, int count, Texture **textures) = 0; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 1f2441d35f..af235b5498 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -17,16 +17,16 @@ public: return caps_; } + ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; + InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) override; BlendState *CreateBlendState(const BlendStateDesc &desc) override; SamplerState *CreateSamplerState(const SamplerStateDesc &desc) override; RasterState *CreateRasterState(const RasterStateDesc &desc) override; Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override; Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override; - InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override; Texture *CreateTexture() override; Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override; - ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override; void BindTextures(int start, int count, Texture **textures) override; void BindSamplerStates(int start, int count, SamplerState **states) override; @@ -37,6 +37,9 @@ public: // Raster state void SetScissorRect(int left, int top, int width, int height) override; void SetViewports(int count, Viewport *viewports) override; + void SetBlendFactor(float color[4]) override { + memcpy(blendFactor_, color, sizeof(float) * 4); + } void Draw(Buffer *vdata, int vertexCount, int offset) override; void DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; @@ -56,10 +59,13 @@ public: } private: + void ApplyCurrentState(); + ID3D11Device *device_; ID3D11DeviceContext *context_; D3D11Pipeline *curPipeline_; DeviceCaps caps_; + float blendFactor_[4]; }; @@ -87,6 +93,9 @@ void D3D11DrawContext::SetScissorRect(int left, int top, int width, int height) class D3D11DepthStencilState : public DepthStencilState { public: + ~D3D11DepthStencilState() { + dss->Release(); + } ID3D11DepthStencilState *dss; }; @@ -145,6 +154,9 @@ static const D3D11_BLEND blendToD3D11[] = { class D3D11BlendState : public BlendState { public: + ~D3D11BlendState() { + bs->Release(); + } ID3D11BlendState *bs; }; @@ -167,6 +179,136 @@ BlendState *D3D11DrawContext::CreateBlendState(const BlendStateDesc &desc) { return nullptr; } +class D3D11RasterState : public RasterState { +public: + ~D3D11RasterState() { + rs->Release(); + } + ID3D11RasterizerState *rs; +}; + +RasterState *D3D11DrawContext::CreateRasterState(const RasterStateDesc &desc) { + D3D11RasterState *rs = new D3D11RasterState(); + D3D11_RASTERIZER_DESC d3ddesc{}; + d3ddesc.FillMode = D3D11_FILL_SOLID; + switch (desc.cull) { + case CullMode::BACK: d3ddesc.CullMode = D3D11_CULL_BACK; break; + case CullMode::FRONT: d3ddesc.CullMode = D3D11_CULL_FRONT; break; + default: + case CullMode::NONE: d3ddesc.CullMode = D3D11_CULL_NONE; break; + } + d3ddesc.FrontCounterClockwise = desc.frontFace == Facing::CCW; + if (SUCCEEDED(device_->CreateRasterizerState(&d3ddesc, &rs->rs))) + return rs; + delete rs; + return nullptr; +} + +class D3D11SamplerState : public SamplerState { +public: + ~D3D11SamplerState() { + ss->Release(); + } + ID3D11SamplerState *ss; +}; + +static const D3D11_TEXTURE_ADDRESS_MODE taddrToD3D11[] = { + D3D11_TEXTURE_ADDRESS_WRAP, + D3D11_TEXTURE_ADDRESS_MIRROR, + D3D11_TEXTURE_ADDRESS_CLAMP, + D3D11_TEXTURE_ADDRESS_BORDER, +}; + +SamplerState *D3D11DrawContext::CreateSamplerState(const SamplerStateDesc &desc) { + D3D11SamplerState *ss = new D3D11SamplerState(); + D3D11_SAMPLER_DESC d3ddesc{}; + d3ddesc.AddressU = taddrToD3D11[(int)desc.wrapU]; + d3ddesc.AddressV = taddrToD3D11[(int)desc.wrapV]; + d3ddesc.AddressW = taddrToD3D11[(int)desc.wrapW]; + // TODO: Needs improvement + d3ddesc.Filter = desc.magFilter == TextureFilter::LINEAR ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT; + d3ddesc.MaxAnisotropy = desc.maxAniso; + d3ddesc.ComparisonFunc = compareToD3D11[(int)desc.shadowCompareFunc]; + if (SUCCEEDED(device_->CreateSamplerState(&d3ddesc, &ss->ss))) + return ss; + delete ss; + return nullptr; +} + +// Input layout creation is delayed to pipeline creation, as we need the vertex shader bytecode. +class D3D11InputLayout : public InputLayout { +public: + InputLayoutDesc desc; +}; + +InputLayout *D3D11DrawContext::CreateInputLayout(const InputLayoutDesc &desc) { + D3D11InputLayout *inputLayout = new D3D11InputLayout(); + inputLayout->desc = desc; + return inputLayout; +} + +class D3D11Pipeline : public Pipeline { +public: + ~D3D11Pipeline() { + input->Release(); + blend->Release(); + depth->Release(); + raster->Release(); + il->Release(); + } + // TODO: Refactor away these. + void SetVector(const char *name, float *value, int n) { } + void SetMatrix4x4(const char *name, const float value[16]) { } // pshaders don't usually have matrices + bool RequiresBuffer() { + return true; + } + + D3D11InputLayout *input; + ID3D11InputLayout *il = nullptr; + D3D11BlendState *blend; + D3D11DepthStencilState *depth; + D3D11RasterState *raster; +}; + +Pipeline *D3D11DrawContext::CreateGraphicsPipeline(const PipelineDesc &desc) { + D3D11Pipeline *dPipeline = new D3D11Pipeline(); + dPipeline->blend = (D3D11BlendState *)desc.blend; + dPipeline->depth = (D3D11DepthStencilState *)desc.depthStencil; + dPipeline->input = (D3D11InputLayout *)desc.inputLayout; + dPipeline->raster = (D3D11RasterState *)desc.raster; + dPipeline->blend->AddRef(); + dPipeline->depth->AddRef(); + dPipeline->input->AddRef(); + dPipeline->raster->AddRef(); + // Can finally create the input layout + + auto &inputDesc = dPipeline->input->desc; + std::vector elements; + device_->CreateInputLayout(elements.data(), elements.size(), shaderBytecode, shaderBytecodeSize, &dPipeline->il); + return dPipeline; +} + +void D3D11DrawContext::BindPipeline(Pipeline *pipeline) { + D3D11Pipeline *dPipeline = (D3D11Pipeline *)pipeline; + curPipeline_ = dPipeline; +} + +void D3D11DrawContext::ApplyCurrentState() { + +} + +void D3D11DrawContext::Draw(Buffer *vdata, int vertexCount, int offset) { + +} + +void D3D11DrawContext::DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) { + +} + +void D3D11DrawContext::DrawUP(const void *vdata, int vertexCount) { + +} + #endif DrawContext *T3DCreateD3D11Context(ID3D11Device *device, ID3D11DeviceContext *context) { diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 0799ca377a..de63dd431c 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -540,6 +540,7 @@ public: // Raster state void SetScissorRect(int left, int top, int width, int height) override; void SetViewports(int count, Viewport *viewports) override; + void SetBlendFactor(float color[4]) override; void Draw(Buffer *vdata, int vertexCount, int offset) override; void DrawIndexed(Buffer *vdata, Buffer *idata, int vertexCount, int offset) override; @@ -676,7 +677,7 @@ RasterState *D3D9Context::CreateRasterState(const RasterStateDesc &desc) { if (desc.cull == CullMode::NONE) { return rs; } - switch (desc.facing) { + switch (desc.frontFace) { case Facing::CW: switch (desc.cull) { case CullMode::FRONT: rs->cullMode = D3DCULL_CCW; break; @@ -842,6 +843,14 @@ void D3D9Context::SetViewports(int count, Viewport *viewports) { device_->SetViewport(&vp); } +void D3D9Context::SetBlendFactor(float color[4]) { + uint32_t r = (uint32_t)(color[0] * 255.0f); + uint32_t g = (uint32_t)(color[1] * 255.0f); + uint32_t b = (uint32_t)(color[2] * 255.0f); + uint32_t a = (uint32_t)(color[3] * 255.0f); + device_->SetRenderState(D3DRS_BLENDFACTOR, r | (g << 8) | (b << 16) | (a << 24)); +} + bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const char *source) { LPD3DXMACRO defines = NULL; LPD3DXINCLUDE includes = NULL; diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 820d3b5629..e9e9986320 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -538,6 +538,10 @@ public: #endif } + void SetBlendFactor(float color[4]) override { + glBlendColor(color[0], color[1], color[2], color[3]); + } + void BindTextures(int start, int count, Texture **textures) override; void BindPipeline(Pipeline *pipeline) override; @@ -852,7 +856,7 @@ RasterState *OpenGLContext::CreateRasterState(const RasterStateDesc &desc) { return rs; } rs->cullEnable = GL_TRUE; - switch (desc.facing) { + switch (desc.frontFace) { case Facing::CW: rs->frontFace = GL_CW; break; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 37b806df61..192dadc2bd 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -155,7 +155,7 @@ class VKRasterState : public RasterState { public: VKRasterState(VulkanContext *vulkan, const RasterStateDesc &desc) { cullFace = desc.cull; - frontFace = desc.facing; + frontFace = desc.frontFace; } Facing frontFace; CullMode cullFace; @@ -368,6 +368,7 @@ public: void SetScissorRect(int left, int top, int width, int height) override; void SetViewports(int count, Viewport *viewports) override; + void SetBlendFactor(float color[4]) override; void BindSamplerStates(int start, int count, SamplerState **state) override; void BindTextures(int start, int count, Texture **textures) override; @@ -898,6 +899,10 @@ void VKContext::SetViewports(int count, Viewport *viewports) { viewportDirty_ = true; } +void VKContext::SetBlendFactor(float color[4]) { + vkCmdSetBlendConstants(cmd_, color); +} + void VKContext::ApplyDynamicState() { if (scissorDirty_) { vkCmdSetScissor(cmd_, 0, 1, &scissor_);