A little more D3D11, BlendFactor

This commit is contained in:
Henrik Rydgård 2016-12-27 15:52:03 +01:00
parent 75cbf4065b
commit 377561865a
6 changed files with 168 additions and 7 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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<D3D11_INPUT_ELEMENT_DESC> 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) {

View File

@ -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;

View File

@ -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;

View File

@ -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_);