592 lines
22 KiB
C
592 lines
22 KiB
C
#include "pipeline.h"
|
|
|
|
#include <kinc/graphics5/graphics.h>
|
|
#include <kinc/graphics5/pipeline.h>
|
|
#include <kinc/graphics5/shader.h>
|
|
#include <kinc/log.h>
|
|
|
|
#include <kinc/backend/SystemMicrosoft.h>
|
|
|
|
void kinc_g5_internal_setConstants(kinc_g5_command_list_t *commandList, kinc_g5_pipeline_t *pipeline) {
|
|
/*if (currentProgram->vertexShader->constantsSize > 0) {
|
|
context->UpdateSubresource(currentProgram->vertexConstantBuffer, 0, nullptr, vertexConstants, 0, 0);
|
|
context->VSSetConstantBuffers(0, 1, ¤tProgram->vertexConstantBuffer);
|
|
}
|
|
if (currentProgram->fragmentShader->constantsSize > 0) {
|
|
context->UpdateSubresource(currentProgram->fragmentConstantBuffer, 0, nullptr, fragmentConstants, 0, 0);
|
|
context->PSSetConstantBuffers(0, 1, ¤tProgram->fragmentConstantBuffer);
|
|
}
|
|
if (currentProgram->geometryShader != nullptr && currentProgram->geometryShader->constantsSize > 0) {
|
|
context->UpdateSubresource(currentProgram->geometryConstantBuffer, 0, nullptr, geometryConstants, 0, 0);
|
|
context->GSSetConstantBuffers(0, 1, ¤tProgram->geometryConstantBuffer);
|
|
}
|
|
if (currentProgram->tessControlShader != nullptr && currentProgram->tessControlShader->constantsSize > 0) {
|
|
context->UpdateSubresource(currentProgram->tessControlConstantBuffer, 0, nullptr, tessControlConstants, 0, 0);
|
|
context->HSSetConstantBuffers(0, 1, ¤tProgram->tessControlConstantBuffer);
|
|
}
|
|
if (currentProgram->tessEvalShader != nullptr && currentProgram->tessEvalShader->constantsSize > 0) {
|
|
context->UpdateSubresource(currentProgram->tessEvalConstantBuffer, 0, nullptr, tessEvalConstants, 0, 0);
|
|
context->DSSetConstantBuffers(0, 1, ¤tProgram->tessEvalConstantBuffer);
|
|
}
|
|
*/
|
|
|
|
commandList->impl._commandList->SetPipelineState(pipeline->impl.pso);
|
|
#ifdef KORE_DXC
|
|
// commandList->SetGraphicsRootSignature(pipeline->impl.rootSignature);
|
|
commandList->impl._commandList->SetGraphicsRootSignature(globalRootSignature);
|
|
#else
|
|
commandList->impl._commandList->SetGraphicsRootSignature(globalRootSignature);
|
|
#endif
|
|
|
|
if (pipeline->impl.textures > 0) {
|
|
kinc_g5_internal_set_textures(commandList);
|
|
}
|
|
}
|
|
|
|
void kinc_g5_pipeline_init(kinc_g5_pipeline_t *pipe) {
|
|
kinc_g5_internal_pipeline_init(pipe);
|
|
}
|
|
|
|
void kinc_g5_pipeline_destroy(kinc_g5_pipeline_t *pipe) {
|
|
if (pipe->impl.pso != NULL) {
|
|
pipe->impl.pso->Release();
|
|
pipe->impl.pso = NULL;
|
|
}
|
|
}
|
|
|
|
// void PipelineState5Impl::set(Graphics5::PipelineState* pipeline) {
|
|
//_current = this;
|
|
// context->VSSetShader((ID3D11VertexShader*)vertexShader->shader, nullptr, 0);
|
|
// context->PSSetShader((ID3D11PixelShader*)fragmentShader->shader, nullptr, 0);
|
|
|
|
// if (geometryShader != nullptr) context->GSSetShader((ID3D11GeometryShader*)geometryShader->shader, nullptr, 0);
|
|
// if (tessControlShader != nullptr) context->HSSetShader((ID3D11HullShader*)tessControlShader->shader, nullptr, 0);
|
|
// if (tessEvalShader != nullptr) context->DSSetShader((ID3D11DomainShader*)tessEvalShader->shader, nullptr, 0);
|
|
|
|
// context->IASetInputLayout(inputLayout);
|
|
//}
|
|
|
|
#define MAX_SHADER_THING 32
|
|
|
|
static ShaderConstant findConstant(kinc_g5_shader_t *shader, const char *name) {
|
|
if (shader != NULL) {
|
|
for (int i = 0; i < MAX_SHADER_THING; ++i) {
|
|
if (strcmp(shader->impl.constants[i].name, name) == 0) {
|
|
return shader->impl.constants[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
ShaderConstant constant;
|
|
constant.name[0] = 0;
|
|
constant.offset = -1;
|
|
constant.size = 0;
|
|
return constant;
|
|
}
|
|
|
|
static ShaderTexture findTexture(kinc_g5_shader_t *shader, const char *name) {
|
|
for (int i = 0; i < MAX_SHADER_THING; ++i) {
|
|
if (strcmp(shader->impl.textures[i].name, name) == 0) {
|
|
return shader->impl.textures[i];
|
|
}
|
|
}
|
|
|
|
ShaderTexture texture;
|
|
texture.name[0] = 0;
|
|
texture.texture = -1;
|
|
return texture;
|
|
}
|
|
|
|
static ShaderAttribute findAttribute(kinc_g5_shader_t *shader, const char *name) {
|
|
for (int i = 0; i < MAX_SHADER_THING; ++i) {
|
|
if (strcmp(shader->impl.attributes[i].name, name) == 0) {
|
|
return shader->impl.attributes[i];
|
|
}
|
|
}
|
|
|
|
ShaderAttribute attribute;
|
|
attribute.name[0] = 0;
|
|
attribute.attribute = -1;
|
|
return attribute;
|
|
}
|
|
|
|
kinc_g5_constant_location_t kinc_g5_pipeline_get_constant_location(struct kinc_g5_pipeline *pipe, const char *name) {
|
|
kinc_g5_constant_location_t location;
|
|
|
|
{
|
|
ShaderConstant constant = findConstant(pipe->vertexShader, name);
|
|
location.impl.vertexOffset = constant.offset;
|
|
location.impl.vertexSize = constant.size;
|
|
}
|
|
|
|
{
|
|
ShaderConstant constant = findConstant(pipe->fragmentShader, name);
|
|
location.impl.fragmentOffset = constant.offset;
|
|
location.impl.fragmentSize = constant.size;
|
|
}
|
|
|
|
location.impl.computeOffset = 0;
|
|
location.impl.computeSize = 0;
|
|
|
|
{
|
|
ShaderConstant constant = findConstant(pipe->geometryShader, name);
|
|
location.impl.geometryOffset = constant.offset;
|
|
location.impl.geometrySize = constant.size;
|
|
}
|
|
|
|
{
|
|
ShaderConstant constant = findConstant(pipe->tessellationControlShader, name);
|
|
location.impl.tessControlOffset = constant.offset;
|
|
location.impl.tessControlSize = constant.size;
|
|
}
|
|
|
|
{
|
|
ShaderConstant constant = findConstant(pipe->tessellationEvaluationShader, name);
|
|
location.impl.tessEvalOffset = constant.offset;
|
|
location.impl.tessEvalSize = constant.size;
|
|
}
|
|
|
|
return location;
|
|
}
|
|
|
|
kinc_g5_texture_unit_t kinc_g5_pipeline_get_texture_unit(kinc_g5_pipeline_t *pipe, const char *name) {
|
|
kinc_g5_texture_unit_t unit;
|
|
for (int i = 0; i < KINC_G5_SHADER_TYPE_COUNT; ++i) {
|
|
unit.stages[i] = -1;
|
|
}
|
|
|
|
ShaderTexture vertexTexture = findTexture(pipe->vertexShader, name);
|
|
if (vertexTexture.texture != -1) {
|
|
unit.stages[KINC_G5_SHADER_TYPE_VERTEX] = vertexTexture.texture;
|
|
}
|
|
else {
|
|
ShaderTexture fragmentTexture = findTexture(pipe->fragmentShader, name);
|
|
unit.stages[KINC_G5_SHADER_TYPE_FRAGMENT] = fragmentTexture.texture;
|
|
}
|
|
return unit;
|
|
}
|
|
|
|
static D3D12_BLEND convert_blend_factor(kinc_g5_blending_factor_t factor) {
|
|
switch (factor) {
|
|
case KINC_G5_BLEND_ONE:
|
|
return D3D12_BLEND_ONE;
|
|
case KINC_G5_BLEND_ZERO:
|
|
return D3D12_BLEND_ZERO;
|
|
case KINC_G5_BLEND_SOURCE_ALPHA:
|
|
return D3D12_BLEND_SRC_ALPHA;
|
|
case KINC_G5_BLEND_DEST_ALPHA:
|
|
return D3D12_BLEND_DEST_ALPHA;
|
|
case KINC_G5_BLEND_INV_SOURCE_ALPHA:
|
|
return D3D12_BLEND_INV_SRC_ALPHA;
|
|
case KINC_G5_BLEND_INV_DEST_ALPHA:
|
|
return D3D12_BLEND_INV_DEST_ALPHA;
|
|
case KINC_G5_BLEND_SOURCE_COLOR:
|
|
return D3D12_BLEND_SRC_COLOR;
|
|
case KINC_G5_BLEND_DEST_COLOR:
|
|
return D3D12_BLEND_DEST_COLOR;
|
|
case KINC_G5_BLEND_INV_SOURCE_COLOR:
|
|
return D3D12_BLEND_INV_SRC_COLOR;
|
|
case KINC_G5_BLEND_INV_DEST_COLOR:
|
|
return D3D12_BLEND_INV_DEST_COLOR;
|
|
case KINC_G5_BLEND_CONSTANT:
|
|
return D3D12_BLEND_BLEND_FACTOR;
|
|
case KINC_G5_BLEND_INV_CONSTANT:
|
|
return D3D12_BLEND_INV_BLEND_FACTOR;
|
|
default:
|
|
assert(false);
|
|
return D3D12_BLEND_ONE;
|
|
}
|
|
}
|
|
|
|
static D3D12_BLEND_OP convert_blend_operation(kinc_g5_blending_operation_t op) {
|
|
switch (op) {
|
|
case KINC_G5_BLENDOP_ADD:
|
|
return D3D12_BLEND_OP_ADD;
|
|
case KINC_G5_BLENDOP_SUBTRACT:
|
|
return D3D12_BLEND_OP_SUBTRACT;
|
|
case KINC_G5_BLENDOP_REVERSE_SUBTRACT:
|
|
return D3D12_BLEND_OP_REV_SUBTRACT;
|
|
case KINC_G5_BLENDOP_MIN:
|
|
return D3D12_BLEND_OP_MIN;
|
|
case KINC_G5_BLENDOP_MAX:
|
|
return D3D12_BLEND_OP_MAX;
|
|
default:
|
|
assert(false);
|
|
return D3D12_BLEND_OP_ADD;
|
|
}
|
|
}
|
|
|
|
static D3D12_CULL_MODE convert_cull_mode(kinc_g5_cull_mode_t cullMode) {
|
|
switch (cullMode) {
|
|
case KINC_G5_CULL_MODE_CLOCKWISE:
|
|
return D3D12_CULL_MODE_FRONT;
|
|
case KINC_G5_CULL_MODE_COUNTERCLOCKWISE:
|
|
return D3D12_CULL_MODE_BACK;
|
|
case KINC_G5_CULL_MODE_NEVER:
|
|
default:
|
|
return D3D12_CULL_MODE_NONE;
|
|
}
|
|
}
|
|
|
|
static D3D12_COMPARISON_FUNC convert_compare_mode(kinc_g5_compare_mode_t compare) {
|
|
switch (compare) {
|
|
default:
|
|
case KINC_G5_COMPARE_MODE_ALWAYS:
|
|
return D3D12_COMPARISON_FUNC_ALWAYS;
|
|
case KINC_G5_COMPARE_MODE_NEVER:
|
|
return D3D12_COMPARISON_FUNC_NEVER;
|
|
case KINC_G5_COMPARE_MODE_EQUAL:
|
|
return D3D12_COMPARISON_FUNC_EQUAL;
|
|
case KINC_G5_COMPARE_MODE_NOT_EQUAL:
|
|
return D3D12_COMPARISON_FUNC_NOT_EQUAL;
|
|
case KINC_G5_COMPARE_MODE_LESS:
|
|
return D3D12_COMPARISON_FUNC_LESS;
|
|
case KINC_G5_COMPARE_MODE_LESS_EQUAL:
|
|
return D3D12_COMPARISON_FUNC_LESS_EQUAL;
|
|
case KINC_G5_COMPARE_MODE_GREATER:
|
|
return D3D12_COMPARISON_FUNC_GREATER;
|
|
case KINC_G5_COMPARE_MODE_GREATER_EQUAL:
|
|
return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
|
|
}
|
|
}
|
|
|
|
static DXGI_FORMAT convert_format(kinc_g5_render_target_format_t format) {
|
|
switch (format) {
|
|
case KINC_G5_RENDER_TARGET_FORMAT_128BIT_FLOAT:
|
|
return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
|
case KINC_G5_RENDER_TARGET_FORMAT_64BIT_FLOAT:
|
|
return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
|
case KINC_G5_RENDER_TARGET_FORMAT_32BIT_RED_FLOAT:
|
|
return DXGI_FORMAT_R32_FLOAT;
|
|
case KINC_G5_RENDER_TARGET_FORMAT_16BIT_RED_FLOAT:
|
|
return DXGI_FORMAT_R16_FLOAT;
|
|
case KINC_G5_RENDER_TARGET_FORMAT_8BIT_RED:
|
|
return DXGI_FORMAT_R8_UNORM;
|
|
case KINC_G5_RENDER_TARGET_FORMAT_32BIT:
|
|
default:
|
|
#ifdef KORE_WINDOWS
|
|
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
#else
|
|
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static void set_blend_state(D3D12_BLEND_DESC *blend_desc, kinc_g5_pipeline_t *pipe, int target) {
|
|
blend_desc->RenderTarget[target].BlendEnable = pipe->blend_source != KINC_G5_BLEND_ONE || pipe->blend_destination != KINC_G5_BLEND_ZERO ||
|
|
pipe->alpha_blend_source != KINC_G5_BLEND_ONE || pipe->alpha_blend_destination != KINC_G5_BLEND_ZERO;
|
|
blend_desc->RenderTarget[target].SrcBlend = convert_blend_factor(pipe->blend_source);
|
|
blend_desc->RenderTarget[target].DestBlend = convert_blend_factor(pipe->blend_destination);
|
|
blend_desc->RenderTarget[target].BlendOp = convert_blend_operation(pipe->blend_operation);
|
|
blend_desc->RenderTarget[target].SrcBlendAlpha = convert_blend_factor(pipe->alpha_blend_source);
|
|
blend_desc->RenderTarget[target].DestBlendAlpha = convert_blend_factor(pipe->alpha_blend_destination);
|
|
blend_desc->RenderTarget[target].BlendOpAlpha = convert_blend_operation(pipe->alpha_blend_operation);
|
|
blend_desc->RenderTarget[target].RenderTargetWriteMask =
|
|
(((pipe->colorWriteMaskRed[target] ? D3D12_COLOR_WRITE_ENABLE_RED : 0) | (pipe->colorWriteMaskGreen[target] ? D3D12_COLOR_WRITE_ENABLE_GREEN : 0)) |
|
|
(pipe->colorWriteMaskBlue[target] ? D3D12_COLOR_WRITE_ENABLE_BLUE : 0)) |
|
|
(pipe->colorWriteMaskAlpha[target] ? D3D12_COLOR_WRITE_ENABLE_ALPHA : 0);
|
|
}
|
|
|
|
void kinc_g5_pipeline_compile(kinc_g5_pipeline_t *pipe) {
|
|
// TODO FLOAT4x4
|
|
int vertexAttributeCount = 0;
|
|
for (int i = 0; i < 16; ++i) {
|
|
if (pipe->inputLayout[i] == NULL) {
|
|
break;
|
|
}
|
|
vertexAttributeCount += pipe->inputLayout[i]->size;
|
|
}
|
|
D3D12_INPUT_ELEMENT_DESC *vertexDesc = (D3D12_INPUT_ELEMENT_DESC *)alloca(sizeof(D3D12_INPUT_ELEMENT_DESC) * vertexAttributeCount);
|
|
ZeroMemory(vertexDesc, sizeof(D3D12_INPUT_ELEMENT_DESC) * vertexAttributeCount);
|
|
int curAttr = 0;
|
|
for (int stream = 0; pipe->inputLayout[stream] != NULL; ++stream) {
|
|
for (int i = 0; i < pipe->inputLayout[stream]->size; ++i) {
|
|
vertexDesc[curAttr].SemanticName = "TEXCOORD";
|
|
#ifdef KINC_KONG
|
|
vertexDesc[curAttr].SemanticIndex = i;
|
|
#else
|
|
vertexDesc[curAttr].SemanticIndex = findAttribute(pipe->vertexShader, pipe->inputLayout[stream]->elements[i].name).attribute;
|
|
#endif
|
|
vertexDesc[curAttr].InputSlot = stream;
|
|
vertexDesc[curAttr].AlignedByteOffset = (i == 0) ? 0 : D3D12_APPEND_ALIGNED_ELEMENT;
|
|
vertexDesc[curAttr].InputSlotClass =
|
|
pipe->inputLayout[stream]->instanced ? D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA : D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
|
vertexDesc[curAttr].InstanceDataStepRate = pipe->inputLayout[stream]->instanced ? 1 : 0;
|
|
|
|
switch (pipe->inputLayout[stream]->elements[i].data) {
|
|
case KINC_G4_VERTEX_DATA_F32_1X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32_FLOAT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_F32_2X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32_FLOAT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_F32_3X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_F32_4X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I8_1X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U8_1X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I8_1X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8_SNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U8_1X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8_UNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I8_2X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U8_2X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I8_2X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8_SNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U8_2X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8_UNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I8_4X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8B8A8_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U8_4X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8B8A8_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I8_4X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8B8A8_SNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U8_4X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I16_1X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U16_1X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I16_1X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16_SNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U16_1X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16_UNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I16_2X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U16_2X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I16_2X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16_SNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U16_2X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16_UNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I16_4X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16B16A16_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U16_4X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16B16A16_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I16_4X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16B16A16_SNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U16_4X_NORMALIZED:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R16G16B16A16_UNORM;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I32_1X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U32_1X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I32_2X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U32_2X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I32_3X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32B32_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U32_3X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32B32_UINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_I32_4X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32B32A32_SINT;
|
|
break;
|
|
case KINC_G4_VERTEX_DATA_U32_4X:
|
|
vertexDesc[curAttr].Format = DXGI_FORMAT_R32G32B32A32_UINT;
|
|
break;
|
|
}
|
|
curAttr++;
|
|
}
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
#ifdef KORE_DXC
|
|
// hr = device->CreateRootSignature(0, pipe->vertexShader->impl.data, pipe->vertexShader->impl.length, IID_GRAPHICS_PPV_ARGS(&pipe->impl.rootSignature));
|
|
if (hr != S_OK) {
|
|
kinc_log(KINC_LOG_LEVEL_WARNING, "Could not create root signature.");
|
|
}
|
|
pipe->impl.vertexConstantsSize = pipe->vertexShader->impl.constantsSize;
|
|
pipe->impl.fragmentConstantsSize = pipe->fragmentShader->impl.constantsSize;
|
|
#endif
|
|
|
|
pipe->impl.textures = pipe->fragmentShader->impl.texturesCount;
|
|
|
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {0};
|
|
psoDesc.VS.BytecodeLength = pipe->vertexShader->impl.length;
|
|
psoDesc.VS.pShaderBytecode = pipe->vertexShader->impl.data;
|
|
psoDesc.PS.BytecodeLength = pipe->fragmentShader->impl.length;
|
|
psoDesc.PS.pShaderBytecode = pipe->fragmentShader->impl.data;
|
|
#ifdef KORE_DXC
|
|
// psoDesc.pRootSignature = pipe->impl.rootSignature;
|
|
psoDesc.pRootSignature = globalRootSignature;
|
|
#else
|
|
psoDesc.pRootSignature = globalRootSignature;
|
|
#endif
|
|
psoDesc.NumRenderTargets = pipe->colorAttachmentCount;
|
|
for (int i = 0; i < pipe->colorAttachmentCount; ++i) {
|
|
psoDesc.RTVFormats[i] = convert_format(pipe->colorAttachment[i]);
|
|
}
|
|
psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN;
|
|
|
|
psoDesc.InputLayout.NumElements = vertexAttributeCount;
|
|
psoDesc.InputLayout.pInputElementDescs = vertexDesc;
|
|
|
|
psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
|
psoDesc.RasterizerState.CullMode = convert_cull_mode(pipe->cullMode);
|
|
psoDesc.RasterizerState.FrontCounterClockwise = FALSE;
|
|
psoDesc.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
|
|
psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
|
|
psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
|
psoDesc.RasterizerState.DepthClipEnable = TRUE;
|
|
psoDesc.RasterizerState.MultisampleEnable = FALSE;
|
|
psoDesc.RasterizerState.AntialiasedLineEnable = FALSE;
|
|
psoDesc.RasterizerState.ForcedSampleCount = 0;
|
|
psoDesc.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
|
|
|
|
psoDesc.BlendState.AlphaToCoverageEnable = FALSE;
|
|
psoDesc.BlendState.IndependentBlendEnable = FALSE;
|
|
const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = {
|
|
FALSE,
|
|
FALSE,
|
|
D3D12_BLEND_ONE,
|
|
D3D12_BLEND_ZERO,
|
|
D3D12_BLEND_OP_ADD,
|
|
D3D12_BLEND_ONE,
|
|
D3D12_BLEND_ZERO,
|
|
D3D12_BLEND_OP_ADD,
|
|
D3D12_LOGIC_OP_NOOP,
|
|
D3D12_COLOR_WRITE_ENABLE_ALL,
|
|
};
|
|
for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) {
|
|
psoDesc.BlendState.RenderTarget[i] = defaultRenderTargetBlendDesc;
|
|
}
|
|
|
|
bool independentBlend = false;
|
|
for (int i = 1; i < 8; ++i) {
|
|
if (pipe->colorWriteMaskRed[0] != pipe->colorWriteMaskRed[i] || pipe->colorWriteMaskGreen[0] != pipe->colorWriteMaskGreen[i] ||
|
|
pipe->colorWriteMaskBlue[0] != pipe->colorWriteMaskBlue[i] || pipe->colorWriteMaskAlpha[0] != pipe->colorWriteMaskAlpha[i]) {
|
|
independentBlend = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
set_blend_state(&psoDesc.BlendState, pipe, 0);
|
|
if (independentBlend) {
|
|
psoDesc.BlendState.IndependentBlendEnable = true;
|
|
for (int i = 1; i < 8; ++i) {
|
|
set_blend_state(&psoDesc.BlendState, pipe, i);
|
|
}
|
|
}
|
|
|
|
psoDesc.DepthStencilState.DepthEnable = TRUE;
|
|
psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
|
|
psoDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
|
|
psoDesc.DepthStencilState.StencilEnable = FALSE;
|
|
psoDesc.DepthStencilState.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
|
|
psoDesc.DepthStencilState.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
|
|
const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = {D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS};
|
|
psoDesc.DepthStencilState.FrontFace = defaultStencilOp;
|
|
psoDesc.DepthStencilState.BackFace = defaultStencilOp;
|
|
|
|
psoDesc.DepthStencilState.DepthEnable = pipe->depthMode != KINC_G5_COMPARE_MODE_ALWAYS;
|
|
psoDesc.DepthStencilState.DepthWriteMask = pipe->depthWrite ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
|
|
psoDesc.DepthStencilState.DepthFunc = convert_compare_mode(pipe->depthMode);
|
|
psoDesc.DepthStencilState.StencilEnable = false;
|
|
psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
|
|
psoDesc.SampleDesc.Count = 1;
|
|
psoDesc.SampleMask = 0xFFFFFFFF;
|
|
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
|
|
|
hr = device->CreateGraphicsPipelineState(&psoDesc, IID_GRAPHICS_PPV_ARGS(&pipe->impl.pso));
|
|
if (hr != S_OK) {
|
|
kinc_log(KINC_LOG_LEVEL_WARNING, "Could not create pipeline.");
|
|
}
|
|
}
|
|
|
|
void kinc_g5_compute_pipeline_init(kinc_g5_compute_pipeline_t *pipeline) {
|
|
kinc_g5_internal_compute_pipeline_init(pipeline);
|
|
pipeline->impl.pso = NULL;
|
|
}
|
|
|
|
void kinc_g5_compute_pipeline_destroy(kinc_g5_compute_pipeline_t *pipeline) {
|
|
if (pipeline->impl.pso != NULL) {
|
|
pipeline->impl.pso->Release();
|
|
pipeline->impl.pso = NULL;
|
|
}
|
|
}
|
|
|
|
void kinc_g5_compute_pipeline_compile(kinc_g5_compute_pipeline_t *pipeline) {
|
|
HRESULT hr;
|
|
#ifdef KORE_DXC
|
|
/*hr = device->CreateRootSignature(0, pipe->vertexShader->impl.data, pipe->vertexShader->impl.length, IID_GRAPHICS_PPV_ARGS(&pipe->impl.rootSignature));
|
|
if (hr != S_OK) {
|
|
kinc_log(KINC_LOG_LEVEL_WARNING, "Could not create root signature.");
|
|
}
|
|
pipe->impl.vertexConstantsSize = pipe->vertexShader->impl.constantsSize;
|
|
pipe->impl.fragmentConstantsSize = pipe->fragmentShader->impl.constantsSize;*/
|
|
#endif
|
|
|
|
D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {0};
|
|
psoDesc.CS.BytecodeLength = pipeline->compute_shader->impl.length;
|
|
psoDesc.CS.pShaderBytecode = pipeline->compute_shader->impl.data;
|
|
#ifdef KORE_DXC
|
|
// psoDesc.pRootSignature = pipe->impl.rootSignature;
|
|
#else
|
|
psoDesc.pRootSignature = globalComputeRootSignature;
|
|
#endif
|
|
|
|
hr = device->CreateComputePipelineState(&psoDesc, IID_GRAPHICS_PPV_ARGS(&pipeline->impl.pso));
|
|
if (hr != S_OK) {
|
|
kinc_log(KINC_LOG_LEVEL_WARNING, "Could not create pipeline.");
|
|
}
|
|
}
|
|
|
|
kinc_g5_constant_location_t kinc_g5_compute_pipeline_get_constant_location(kinc_g5_compute_pipeline_t *pipeline, const char *name) {
|
|
kinc_g5_constant_location_t location = {0};
|
|
|
|
{
|
|
ShaderConstant constant = findConstant(pipeline->compute_shader, name);
|
|
location.impl.computeOffset = constant.offset;
|
|
location.impl.computeSize = constant.size;
|
|
}
|
|
|
|
return location;
|
|
}
|
|
|
|
kinc_g5_texture_unit_t kinc_g5_compute_pipeline_get_texture_unit(kinc_g5_compute_pipeline_t *pipeline, const char *name) {
|
|
kinc_g5_texture_unit_t unit;
|
|
ShaderTexture texture = findTexture(pipeline->compute_shader, name);
|
|
if (texture.texture != -1) {
|
|
unit.stages[KINC_G5_SHADER_TYPE_COMPUTE] = texture.texture;
|
|
}
|
|
return unit;
|
|
}
|