forked from MoonsideGames/Refresh
First pass at CreateBuffer, SetBufferData, QueueDestroyBuffer, CreateGraphicsPipeline, QueueDestroyGraphicsPipeline, DrawPrimitives, and setting default viewport/scissor rects on render passes
parent
5529a4a9ae
commit
05d200c7fa
|
@ -158,7 +158,7 @@ static D3D11_PRIMITIVE_TOPOLOGY RefreshToD3D11_PrimitiveType[] =
|
||||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP /* TRIANGLESTRIP */
|
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP /* TRIANGLESTRIP */
|
||||||
};
|
};
|
||||||
|
|
||||||
static D3D11_FILL_MODE RefreshToD3D11_PolygonMode[] =
|
static D3D11_FILL_MODE RefreshToD3D11_FillMode[] =
|
||||||
{
|
{
|
||||||
D3D11_FILL_SOLID, /* FILL */
|
D3D11_FILL_SOLID, /* FILL */
|
||||||
D3D11_FILL_WIREFRAME, /* LINE */
|
D3D11_FILL_WIREFRAME, /* LINE */
|
||||||
|
@ -289,6 +289,11 @@ typedef struct D3D11Texture
|
||||||
};
|
};
|
||||||
} D3D11Texture;
|
} D3D11Texture;
|
||||||
|
|
||||||
|
typedef struct D3D11Buffer
|
||||||
|
{
|
||||||
|
ID3D11Buffer *handle;
|
||||||
|
} D3D11Buffer;
|
||||||
|
|
||||||
typedef struct D3D11SwapchainData
|
typedef struct D3D11SwapchainData
|
||||||
{
|
{
|
||||||
IDXGISwapChain* swapchain;
|
IDXGISwapChain* swapchain;
|
||||||
|
@ -327,8 +332,32 @@ typedef struct D3D11ShaderModule
|
||||||
size_t numEntryPoints;
|
size_t numEntryPoints;
|
||||||
const spvc_entry_point *entryPoints;
|
const spvc_entry_point *entryPoints;
|
||||||
ID3D11DeviceChild **shaders; /* ID3D11VertexShader, ID3D11PixelShader, ID3D11ComputeShader */
|
ID3D11DeviceChild **shaders; /* ID3D11VertexShader, ID3D11PixelShader, ID3D11ComputeShader */
|
||||||
|
ID3D10Blob **blobs;
|
||||||
} D3D11ShaderModule;
|
} D3D11ShaderModule;
|
||||||
|
|
||||||
|
typedef struct D3D11GraphicsPipeline
|
||||||
|
{
|
||||||
|
float blendConstants[4];
|
||||||
|
|
||||||
|
int32_t numColorAttachments;
|
||||||
|
int32_t colorAttachmentSampleCounts[MAX_COLOR_TARGET_BINDINGS];
|
||||||
|
DXGI_FORMAT colorAttachmentFormats[MAX_COLOR_TARGET_BINDINGS];
|
||||||
|
ID3D11BlendState *colorAttachmentBlendState;
|
||||||
|
|
||||||
|
uint8_t hasDepthStencilAttachment;
|
||||||
|
DXGI_FORMAT depthStencilAttachmentFormat;
|
||||||
|
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology;
|
||||||
|
uint32_t stencilRef;
|
||||||
|
ID3D11DepthStencilState *depthStencilState;
|
||||||
|
ID3D11RasterizerState *rasterizerState;
|
||||||
|
ID3D11InputLayout *inputLayout;
|
||||||
|
|
||||||
|
Refresh_MultisampleState multisampleState;
|
||||||
|
ID3D11VertexShader *vertexShader;
|
||||||
|
ID3D11PixelShader *fragmentShader;
|
||||||
|
} D3D11GraphicsPipeline;
|
||||||
|
|
||||||
typedef struct D3D11Renderer
|
typedef struct D3D11Renderer
|
||||||
{
|
{
|
||||||
ID3D11Device *device;
|
ID3D11Device *device;
|
||||||
|
@ -351,7 +380,6 @@ typedef struct D3D11Renderer
|
||||||
|
|
||||||
uint8_t debugMode;
|
uint8_t debugMode;
|
||||||
D3D_FEATURE_LEVEL featureLevel;
|
D3D_FEATURE_LEVEL featureLevel;
|
||||||
|
|
||||||
PFN_D3DCOMPILE D3DCompileFunc;
|
PFN_D3DCOMPILE D3DCompileFunc;
|
||||||
} D3D11Renderer;
|
} D3D11Renderer;
|
||||||
|
|
||||||
|
@ -693,7 +721,14 @@ static void D3D11_DrawPrimitives(
|
||||||
uint32_t vertexParamOffset,
|
uint32_t vertexParamOffset,
|
||||||
uint32_t fragmentParamOffset
|
uint32_t fragmentParamOffset
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer;
|
||||||
|
ID3D11DeviceContext_Draw(
|
||||||
|
cmdbuf->context,
|
||||||
|
primitiveCount * 3, /* FIXME: Needs to use a primitive lookup table! */
|
||||||
|
vertexStart
|
||||||
|
);
|
||||||
|
|
||||||
|
/* FIXME: vertex/fragment param offsets */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void D3D11_DispatchCompute(
|
static void D3D11_DispatchCompute(
|
||||||
|
@ -709,6 +744,224 @@ static void D3D11_DispatchCompute(
|
||||||
|
|
||||||
/* State Creation */
|
/* State Creation */
|
||||||
|
|
||||||
|
static ID3D11BlendState* D3D11_INTERNAL_FetchBlendState(
|
||||||
|
D3D11Renderer *renderer,
|
||||||
|
uint32_t numColorAttachments,
|
||||||
|
Refresh_ColorAttachmentDescription *colorAttachments
|
||||||
|
) {
|
||||||
|
ID3D11BlendState *result;
|
||||||
|
D3D11_BLEND_DESC blendDesc;
|
||||||
|
uint32_t i;
|
||||||
|
HRESULT res;
|
||||||
|
|
||||||
|
/* Create a new blend state.
|
||||||
|
* The spec says the driver will not create duplicate states, so there's no need to cache.
|
||||||
|
*/
|
||||||
|
SDL_zero(blendDesc); /* needed for any unused RT entries */
|
||||||
|
|
||||||
|
blendDesc.AlphaToCoverageEnable = FALSE;
|
||||||
|
blendDesc.IndependentBlendEnable = TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < numColorAttachments; i += 1)
|
||||||
|
{
|
||||||
|
blendDesc.RenderTarget[i].BlendEnable = colorAttachments[i].blendState.blendEnable;
|
||||||
|
blendDesc.RenderTarget[i].BlendOp = RefreshToD3D11_BlendOp[
|
||||||
|
colorAttachments[i].blendState.colorBlendOp
|
||||||
|
];
|
||||||
|
blendDesc.RenderTarget[i].BlendOpAlpha = RefreshToD3D11_BlendOp[
|
||||||
|
colorAttachments[i].blendState.alphaBlendOp
|
||||||
|
];
|
||||||
|
blendDesc.RenderTarget[i].DestBlend = RefreshToD3D11_BlendFactor[
|
||||||
|
colorAttachments[i].blendState.dstColorBlendFactor
|
||||||
|
];
|
||||||
|
blendDesc.RenderTarget[i].DestBlendAlpha = RefreshToD3D11_BlendFactor[
|
||||||
|
colorAttachments[i].blendState.dstAlphaBlendFactor
|
||||||
|
];
|
||||||
|
blendDesc.RenderTarget[i].RenderTargetWriteMask = colorAttachments[i].blendState.colorWriteMask;
|
||||||
|
blendDesc.RenderTarget[i].SrcBlend = RefreshToD3D11_BlendFactor[
|
||||||
|
colorAttachments[i].blendState.srcColorBlendFactor
|
||||||
|
];
|
||||||
|
blendDesc.RenderTarget[i].SrcBlendAlpha = RefreshToD3D11_BlendFactor[
|
||||||
|
colorAttachments[i].blendState.srcAlphaBlendFactor
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ID3D11Device_CreateBlendState(
|
||||||
|
renderer->device,
|
||||||
|
&blendDesc,
|
||||||
|
&result
|
||||||
|
);
|
||||||
|
ERROR_CHECK_RETURN("Could not create blend state", NULL);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ID3D11DepthStencilState* D3D11_INTERNAL_FetchDepthStencilState(
|
||||||
|
D3D11Renderer *renderer,
|
||||||
|
Refresh_DepthStencilState depthStencilState
|
||||||
|
) {
|
||||||
|
ID3D11DepthStencilState *result;
|
||||||
|
D3D11_DEPTH_STENCIL_DESC dsDesc;
|
||||||
|
HRESULT res;
|
||||||
|
|
||||||
|
/* Create a new depth-stencil state.
|
||||||
|
* The spec says the driver will not create duplicate states, so there's no need to cache.
|
||||||
|
*/
|
||||||
|
dsDesc.DepthEnable = depthStencilState.depthTestEnable;
|
||||||
|
dsDesc.StencilEnable = depthStencilState.stencilTestEnable;
|
||||||
|
dsDesc.DepthFunc = depthStencilState.compareOp;
|
||||||
|
dsDesc.DepthWriteMask = (
|
||||||
|
depthStencilState.depthWriteEnable ?
|
||||||
|
D3D11_DEPTH_WRITE_MASK_ALL :
|
||||||
|
D3D11_DEPTH_WRITE_MASK_ZERO
|
||||||
|
);
|
||||||
|
|
||||||
|
dsDesc.BackFace.StencilFunc = depthStencilState.backStencilState.compareOp;
|
||||||
|
dsDesc.BackFace.StencilDepthFailOp = depthStencilState.backStencilState.depthFailOp;
|
||||||
|
dsDesc.BackFace.StencilFailOp = depthStencilState.backStencilState.failOp;
|
||||||
|
dsDesc.BackFace.StencilPassOp = depthStencilState.backStencilState.passOp;
|
||||||
|
|
||||||
|
dsDesc.FrontFace.StencilFunc = depthStencilState.frontStencilState.compareOp;
|
||||||
|
dsDesc.FrontFace.StencilDepthFailOp = depthStencilState.frontStencilState.depthFailOp;
|
||||||
|
dsDesc.FrontFace.StencilFailOp = depthStencilState.frontStencilState.failOp;
|
||||||
|
dsDesc.FrontFace.StencilPassOp = depthStencilState.frontStencilState.passOp;
|
||||||
|
|
||||||
|
/* FIXME: D3D11 doesn't have separate read/write masks for each stencil side. What should we do? */
|
||||||
|
dsDesc.StencilReadMask = depthStencilState.backStencilState.compareMask;
|
||||||
|
dsDesc.StencilWriteMask = depthStencilState.backStencilState.writeMask;
|
||||||
|
|
||||||
|
/* FIXME: What do we do with these?
|
||||||
|
* depthStencilState.depthBoundsTestEnable
|
||||||
|
* depthStencilState.maxDepthBounds
|
||||||
|
* depthStencilState.minDepthBounds
|
||||||
|
*/
|
||||||
|
|
||||||
|
res = ID3D11Device_CreateDepthStencilState(
|
||||||
|
renderer->device,
|
||||||
|
&dsDesc,
|
||||||
|
&result
|
||||||
|
);
|
||||||
|
ERROR_CHECK_RETURN("Could not create depth-stencil state", NULL);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ID3D11RasterizerState* D3D11_INTERNAL_FetchRasterizerState(
|
||||||
|
D3D11Renderer *renderer,
|
||||||
|
Refresh_RasterizerState rasterizerState
|
||||||
|
) {
|
||||||
|
ID3D11RasterizerState *result;
|
||||||
|
D3D11_RASTERIZER_DESC rasterizerDesc;
|
||||||
|
HRESULT res;
|
||||||
|
|
||||||
|
/* Create a new rasterizer state.
|
||||||
|
* The spec says the driver will not create duplicate states, so there's no need to cache.
|
||||||
|
*/
|
||||||
|
rasterizerDesc.AntialiasedLineEnable = FALSE;
|
||||||
|
rasterizerDesc.CullMode = RefreshToD3D11_CullMode[rasterizerState.cullMode];
|
||||||
|
rasterizerDesc.DepthBias = (INT) rasterizerState.depthBiasConstantFactor; /* FIXME: Is this cast correct? */
|
||||||
|
rasterizerDesc.DepthBiasClamp = rasterizerState.depthBiasClamp;
|
||||||
|
rasterizerDesc.DepthClipEnable = TRUE; /* FIXME: Do we want this...? */
|
||||||
|
rasterizerDesc.FillMode = RefreshToD3D11_FillMode[rasterizerState.fillMode];
|
||||||
|
rasterizerDesc.FrontCounterClockwise = (rasterizerState.frontFace == REFRESH_FRONTFACE_COUNTER_CLOCKWISE);
|
||||||
|
rasterizerDesc.MultisampleEnable = TRUE; /* only applies to MSAA render targets */
|
||||||
|
rasterizerDesc.ScissorEnable = TRUE;
|
||||||
|
rasterizerDesc.SlopeScaledDepthBias = rasterizerState.depthBiasSlopeFactor;
|
||||||
|
|
||||||
|
res = ID3D11Device_CreateRasterizerState(
|
||||||
|
renderer->device,
|
||||||
|
&rasterizerDesc,
|
||||||
|
&result
|
||||||
|
);
|
||||||
|
ERROR_CHECK_RETURN("Could not create rasterizer state", NULL);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t D3D11_INTERNAL_FindIndexOfVertexBinding(
|
||||||
|
uint32_t targetBinding,
|
||||||
|
const Refresh_VertexBinding *bindings,
|
||||||
|
uint32_t numBindings
|
||||||
|
) {
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < numBindings; i += 1)
|
||||||
|
{
|
||||||
|
if (bindings[i].binding == targetBinding)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Refresh_LogError("Could not find vertex binding %d!", targetBinding);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ID3D11InputLayout* D3D11_INTERNAL_FetchInputLayout(
|
||||||
|
D3D11Renderer *renderer,
|
||||||
|
Refresh_VertexInputState inputState,
|
||||||
|
ID3D10Blob *shaderBlob
|
||||||
|
) {
|
||||||
|
ID3D11InputLayout *result = NULL;
|
||||||
|
D3D11_INPUT_ELEMENT_DESC *elementDescs;
|
||||||
|
uint32_t i, bindingIndex;
|
||||||
|
HRESULT res;
|
||||||
|
|
||||||
|
/* Allocate an array of vertex elements */
|
||||||
|
elementDescs = SDL_stack_alloc(
|
||||||
|
D3D11_INPUT_ELEMENT_DESC,
|
||||||
|
inputState.vertexAttributeCount
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Create the array of input elements */
|
||||||
|
for (i = 0; i < inputState.vertexAttributeCount; i += 1)
|
||||||
|
{
|
||||||
|
elementDescs[i].AlignedByteOffset = inputState.vertexAttributes[i].offset;
|
||||||
|
elementDescs[i].Format = RefreshToD3D11_VertexFormat[
|
||||||
|
inputState.vertexAttributes[i].format
|
||||||
|
];
|
||||||
|
elementDescs[i].InputSlot = inputState.vertexAttributes[i].binding;
|
||||||
|
|
||||||
|
bindingIndex = D3D11_INTERNAL_FindIndexOfVertexBinding(
|
||||||
|
elementDescs[i].InputSlot,
|
||||||
|
inputState.vertexBindings,
|
||||||
|
inputState.vertexBindingCount
|
||||||
|
);
|
||||||
|
elementDescs[i].InputSlotClass = RefreshToD3D11_VertexInputRate[
|
||||||
|
inputState.vertexBindings[bindingIndex].inputRate
|
||||||
|
];
|
||||||
|
/* The spec requires this to be 0 for per-vertex data */
|
||||||
|
elementDescs[i].InstanceDataStepRate = (
|
||||||
|
elementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA ? 1 : 0
|
||||||
|
);
|
||||||
|
|
||||||
|
elementDescs[i].SemanticIndex = inputState.vertexAttributes[i].location;
|
||||||
|
elementDescs[i].SemanticName = "TEXCOORD";
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ID3D11Device_CreateInputLayout(
|
||||||
|
renderer->device,
|
||||||
|
elementDescs,
|
||||||
|
inputState.vertexAttributeCount,
|
||||||
|
(void*) ID3D10Blob_GetBufferPointer(shaderBlob),
|
||||||
|
ID3D10Blob_GetBufferSize(shaderBlob),
|
||||||
|
&result
|
||||||
|
);
|
||||||
|
if (FAILED(res))
|
||||||
|
{
|
||||||
|
Refresh_LogError("Could not create input layout! Error: %X", res);
|
||||||
|
SDL_stack_free(elementDescs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME:
|
||||||
|
* These are not cached by the driver! Should we cache them, or allow duplicates?
|
||||||
|
* If we have one input layout per graphics pipeline maybe that wouldn't be so bad...?
|
||||||
|
*/
|
||||||
|
|
||||||
|
SDL_stack_free(elementDescs);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static Refresh_ComputePipeline* D3D11_CreateComputePipeline(
|
static Refresh_ComputePipeline* D3D11_CreateComputePipeline(
|
||||||
Refresh_Renderer* driverData,
|
Refresh_Renderer* driverData,
|
||||||
Refresh_ComputeShaderInfo* computeShaderInfo
|
Refresh_ComputeShaderInfo* computeShaderInfo
|
||||||
|
@ -720,7 +973,109 @@ static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline(
|
||||||
Refresh_Renderer* driverData,
|
Refresh_Renderer* driverData,
|
||||||
Refresh_GraphicsPipelineCreateInfo* pipelineCreateInfo
|
Refresh_GraphicsPipelineCreateInfo* pipelineCreateInfo
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
||||||
|
D3D11GraphicsPipeline *pipeline = (D3D11GraphicsPipeline*) SDL_malloc(sizeof(D3D11GraphicsPipeline));
|
||||||
|
D3D11ShaderModule* vertShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->vertexShaderInfo.shaderModule;
|
||||||
|
D3D11ShaderModule* fragShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->fragmentShaderInfo.shaderModule;
|
||||||
|
int32_t vertexShaderIndex, fragmentShaderIndex;
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
/* Color attachments */
|
||||||
|
pipeline->numColorAttachments = pipelineCreateInfo->attachmentInfo.colorAttachmentCount;
|
||||||
|
for (i = 0; i < pipeline->numColorAttachments; i += 1)
|
||||||
|
{
|
||||||
|
pipeline->colorAttachmentSampleCounts[i] = RefreshToD3D11_SampleCount[
|
||||||
|
pipelineCreateInfo->attachmentInfo.colorAttachmentDescriptions[i].sampleCount
|
||||||
|
];
|
||||||
|
|
||||||
|
pipeline->colorAttachmentFormats[i] = RefreshToD3D11_SurfaceFormat[
|
||||||
|
pipelineCreateInfo->attachmentInfo.colorAttachmentDescriptions[i].format
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline->blendConstants[0] = pipelineCreateInfo->blendConstants[0];
|
||||||
|
pipeline->blendConstants[1] = pipelineCreateInfo->blendConstants[1];
|
||||||
|
pipeline->blendConstants[2] = pipelineCreateInfo->blendConstants[2];
|
||||||
|
pipeline->blendConstants[3] = pipelineCreateInfo->blendConstants[3];
|
||||||
|
pipeline->multisampleState = pipelineCreateInfo->multisampleState;
|
||||||
|
|
||||||
|
pipeline->colorAttachmentBlendState = D3D11_INTERNAL_FetchBlendState(
|
||||||
|
renderer,
|
||||||
|
pipelineCreateInfo->attachmentInfo.colorAttachmentCount,
|
||||||
|
pipelineCreateInfo->attachmentInfo.colorAttachmentDescriptions
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Depth stencil */
|
||||||
|
pipeline->hasDepthStencilAttachment = pipelineCreateInfo->attachmentInfo.hasDepthStencilAttachment;
|
||||||
|
pipeline->depthStencilAttachmentFormat = RefreshToD3D11_SurfaceFormat[
|
||||||
|
pipelineCreateInfo->attachmentInfo.depthStencilFormat
|
||||||
|
];
|
||||||
|
pipeline->stencilRef = pipelineCreateInfo->depthStencilState.backStencilState.reference; /* FIXME: Should we use front or back? */
|
||||||
|
|
||||||
|
pipeline->depthStencilState = D3D11_INTERNAL_FetchDepthStencilState(
|
||||||
|
renderer,
|
||||||
|
pipelineCreateInfo->depthStencilState
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Rasterizer state */
|
||||||
|
pipeline->primitiveTopology = RefreshToD3D11_PrimitiveType[pipelineCreateInfo->primitiveType];
|
||||||
|
pipeline->rasterizerState = D3D11_INTERNAL_FetchRasterizerState(
|
||||||
|
renderer,
|
||||||
|
pipelineCreateInfo->rasterizerState
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Vertex Shader + Input Layout */
|
||||||
|
vertexShaderIndex = -1;
|
||||||
|
for (i = 0; i < vertShaderModule->numEntryPoints; i += 1)
|
||||||
|
{
|
||||||
|
if ( vertShaderModule->entryPoints[i].execution_model == SpvExecutionModelVertex &&
|
||||||
|
SDL_strcmp(vertShaderModule->entryPoints[i].name, pipelineCreateInfo->vertexShaderInfo.entryPointName) == 0 )
|
||||||
|
{
|
||||||
|
vertexShaderIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vertexShaderIndex == -1)
|
||||||
|
{
|
||||||
|
Refresh_LogError(
|
||||||
|
"Graphics pipeline creation failed! No entry point '%s' exists for the vertex shader!",
|
||||||
|
pipelineCreateInfo->vertexShaderInfo.entryPointName
|
||||||
|
);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline->inputLayout = D3D11_INTERNAL_FetchInputLayout(
|
||||||
|
renderer,
|
||||||
|
pipelineCreateInfo->vertexInputState,
|
||||||
|
vertShaderModule->blobs[vertexShaderIndex]
|
||||||
|
);
|
||||||
|
pipeline->vertexShader = (ID3D11VertexShader*) vertShaderModule->shaders[vertexShaderIndex];
|
||||||
|
|
||||||
|
/* Fragment Shader */
|
||||||
|
fragmentShaderIndex = -1;
|
||||||
|
for (i = 0; i < fragShaderModule->numEntryPoints; i += 1)
|
||||||
|
{
|
||||||
|
if ( fragShaderModule->entryPoints[i].execution_model == SpvExecutionModelFragment &&
|
||||||
|
SDL_strcmp(fragShaderModule->entryPoints[i].name, pipelineCreateInfo->fragmentShaderInfo.entryPointName) == 0 )
|
||||||
|
{
|
||||||
|
fragmentShaderIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fragmentShaderIndex == -1)
|
||||||
|
{
|
||||||
|
Refresh_LogError(
|
||||||
|
"Graphics pipeline creation failed! No entry point '%s' exists for the fragment shader!",
|
||||||
|
pipelineCreateInfo->vertexShaderInfo.entryPointName
|
||||||
|
);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline->fragmentShader = (ID3D11PixelShader*) fragShaderModule->shaders[fragmentShaderIndex];
|
||||||
|
|
||||||
|
/* FIXME: Need to create uniform buffers for the shaders */
|
||||||
|
|
||||||
|
return (Refresh_GraphicsPipeline*) pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Refresh_Sampler* D3D11_CreateSampler(
|
static Refresh_Sampler* D3D11_CreateSampler(
|
||||||
|
@ -744,7 +1099,7 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
spvc_compiler_options compilerOptions;
|
spvc_compiler_options compilerOptions;
|
||||||
char *hlslSource;
|
char *hlslSource;
|
||||||
const char *shaderModel;
|
const char *shaderModel;
|
||||||
ID3DBlob *blob;
|
ID3DBlob **blobs;
|
||||||
ID3DBlob *errorBlob = NULL;
|
ID3DBlob *errorBlob = NULL;
|
||||||
ID3D11DeviceChild **shaders;
|
ID3D11DeviceChild **shaders;
|
||||||
D3D11ShaderModule *shaderModule;
|
D3D11ShaderModule *shaderModule;
|
||||||
|
@ -804,6 +1159,11 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL,
|
SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL,
|
||||||
50 /* shader model 5.0 */
|
50 /* shader model 5.0 */
|
||||||
);
|
);
|
||||||
|
spvc_compiler_options_set_bool(
|
||||||
|
compilerOptions,
|
||||||
|
SPVC_COMPILER_OPTION_FLIP_VERTEX_Y,
|
||||||
|
SPVC_TRUE
|
||||||
|
);
|
||||||
spvc_compiler_install_compiler_options(compiler, compilerOptions);
|
spvc_compiler_install_compiler_options(compiler, compilerOptions);
|
||||||
|
|
||||||
/* Cross compile to HLSL */
|
/* Cross compile to HLSL */
|
||||||
|
@ -817,6 +1177,7 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
|
|
||||||
/* Allocate memory for the D3D11 shader list */
|
/* Allocate memory for the D3D11 shader list */
|
||||||
shaders = (ID3D11DeviceChild**) SDL_malloc(numEntryPoints * sizeof(ID3D11DeviceChild*));
|
shaders = (ID3D11DeviceChild**) SDL_malloc(numEntryPoints * sizeof(ID3D11DeviceChild*));
|
||||||
|
blobs = (ID3D10Blob**) SDL_malloc(numEntryPoints * sizeof(ID3D10Blob*));
|
||||||
|
|
||||||
/* Compile each HLSL entry point into a D3D shader */
|
/* Compile each HLSL entry point into a D3D shader */
|
||||||
for (i = 0; i < numEntryPoints; i += 1)
|
for (i = 0; i < numEntryPoints; i += 1)
|
||||||
|
@ -857,7 +1218,7 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
shaderModel,
|
shaderModel,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
&blob,
|
&blobs[i],
|
||||||
&errorBlob
|
&errorBlob
|
||||||
);
|
);
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
|
@ -879,8 +1240,8 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
case SpvExecutionModelVertex:
|
case SpvExecutionModelVertex:
|
||||||
res = ID3D11Device_CreateVertexShader(
|
res = ID3D11Device_CreateVertexShader(
|
||||||
renderer->device,
|
renderer->device,
|
||||||
ID3D10Blob_GetBufferPointer(blob),
|
ID3D10Blob_GetBufferPointer(blobs[i]),
|
||||||
ID3D10Blob_GetBufferSize(blob),
|
ID3D10Blob_GetBufferSize(blobs[i]),
|
||||||
NULL,
|
NULL,
|
||||||
(ID3D11VertexShader**) &shaders[i]
|
(ID3D11VertexShader**) &shaders[i]
|
||||||
);
|
);
|
||||||
|
@ -889,8 +1250,8 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
case SpvExecutionModelFragment:
|
case SpvExecutionModelFragment:
|
||||||
res = ID3D11Device_CreatePixelShader(
|
res = ID3D11Device_CreatePixelShader(
|
||||||
renderer->device,
|
renderer->device,
|
||||||
ID3D10Blob_GetBufferPointer(blob),
|
ID3D10Blob_GetBufferPointer(blobs[i]),
|
||||||
ID3D10Blob_GetBufferSize(blob),
|
ID3D10Blob_GetBufferSize(blobs[i]),
|
||||||
NULL,
|
NULL,
|
||||||
(ID3D11PixelShader**) &shaders[i]
|
(ID3D11PixelShader**) &shaders[i]
|
||||||
);
|
);
|
||||||
|
@ -899,8 +1260,8 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
case SpvExecutionModelGLCompute:
|
case SpvExecutionModelGLCompute:
|
||||||
res = ID3D11Device_CreateComputeShader(
|
res = ID3D11Device_CreateComputeShader(
|
||||||
renderer->device,
|
renderer->device,
|
||||||
ID3D10Blob_GetBufferPointer(blob),
|
ID3D10Blob_GetBufferPointer(blobs[i]),
|
||||||
ID3D10Blob_GetBufferSize(blob),
|
ID3D10Blob_GetBufferSize(blobs[i]),
|
||||||
NULL,
|
NULL,
|
||||||
(ID3D11ComputeShader**) &shaders[i]
|
(ID3D11ComputeShader**) &shaders[i]
|
||||||
);
|
);
|
||||||
|
@ -921,6 +1282,7 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
||||||
shaderModule->entryPoints = entryPoints;
|
shaderModule->entryPoints = entryPoints;
|
||||||
shaderModule->numEntryPoints = numEntryPoints;
|
shaderModule->numEntryPoints = numEntryPoints;
|
||||||
shaderModule->shaders = shaders;
|
shaderModule->shaders = shaders;
|
||||||
|
shaderModule->blobs = blobs;
|
||||||
return (Refresh_ShaderModule*) shaderModule;
|
return (Refresh_ShaderModule*) shaderModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,7 +1298,45 @@ static Refresh_Buffer* D3D11_CreateBuffer(
|
||||||
Refresh_BufferUsageFlags usageFlags,
|
Refresh_BufferUsageFlags usageFlags,
|
||||||
uint32_t sizeInBytes
|
uint32_t sizeInBytes
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
||||||
|
ID3D11Buffer *bufferHandle;
|
||||||
|
D3D11_BUFFER_DESC bufferDesc;
|
||||||
|
uint32_t bindFlags = 0;
|
||||||
|
D3D11Buffer *result;
|
||||||
|
HRESULT res;
|
||||||
|
|
||||||
|
if (usageFlags & REFRESH_BUFFERUSAGE_INDEX_BIT)
|
||||||
|
{
|
||||||
|
bindFlags |= D3D11_BIND_INDEX_BUFFER;
|
||||||
|
}
|
||||||
|
if (usageFlags & REFRESH_BUFFERUSAGE_VERTEX_BIT)
|
||||||
|
{
|
||||||
|
bindFlags |= D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
}
|
||||||
|
if (usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT)
|
||||||
|
{
|
||||||
|
bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
||||||
|
bindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferDesc.BindFlags = bindFlags;
|
||||||
|
bufferDesc.ByteWidth = sizeInBytes;
|
||||||
|
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
bufferDesc.MiscFlags = 0;
|
||||||
|
bufferDesc.StructureByteStride = 0; /* FIXME: Is this right...? */
|
||||||
|
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
|
||||||
|
res = ID3D11Device_CreateBuffer(
|
||||||
|
renderer->device,
|
||||||
|
&bufferDesc,
|
||||||
|
NULL,
|
||||||
|
&bufferHandle
|
||||||
|
);
|
||||||
|
ERROR_CHECK_RETURN("Could not create buffer", NULL);
|
||||||
|
|
||||||
|
result = (D3D11Buffer*) SDL_malloc(sizeof(D3D11Buffer));
|
||||||
|
result->handle = bufferHandle;
|
||||||
|
return (Refresh_Buffer*) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setters */
|
/* Setters */
|
||||||
|
@ -987,14 +1387,45 @@ static void D3D11_CopyTextureToBuffer(
|
||||||
}
|
}
|
||||||
|
|
||||||
static void D3D11_SetBufferData(
|
static void D3D11_SetBufferData(
|
||||||
Refresh_Renderer* driverData,
|
Refresh_Renderer *driverData,
|
||||||
Refresh_CommandBuffer* commandBuffer,
|
Refresh_CommandBuffer *commandBuffer,
|
||||||
Refresh_Buffer* buffer,
|
Refresh_Buffer *buffer,
|
||||||
uint32_t offsetInBytes,
|
uint32_t offsetInBytes,
|
||||||
void* data,
|
void *data,
|
||||||
uint32_t dataLength
|
uint32_t dataLength
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
||||||
|
D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer;
|
||||||
|
D3D11Buffer *buf = (D3D11Buffer*) buffer;
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mappedSubresource;
|
||||||
|
HRESULT res;
|
||||||
|
|
||||||
|
/* FIXME: How should we handle partial updates? */
|
||||||
|
|
||||||
|
/* Map the buffer */
|
||||||
|
res = ID3D11DeviceContext_Map(
|
||||||
|
cmdbuf->context,
|
||||||
|
(ID3D11Resource*) buf->handle,
|
||||||
|
0,
|
||||||
|
D3D11_MAP_WRITE_DISCARD,
|
||||||
|
0,
|
||||||
|
&mappedSubresource
|
||||||
|
);
|
||||||
|
ERROR_CHECK_RETURN("Could not map buffer",);
|
||||||
|
|
||||||
|
/* Copy in the data */
|
||||||
|
SDL_memcpy(
|
||||||
|
(uint8_t*) mappedSubresource.pData + offsetInBytes,
|
||||||
|
data,
|
||||||
|
dataLength
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Unmap the buffer */
|
||||||
|
ID3D11DeviceContext_Unmap(
|
||||||
|
cmdbuf->context,
|
||||||
|
(ID3D11Resource*) buf->handle,
|
||||||
|
0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t D3D11_PushVertexShaderUniforms(
|
static uint32_t D3D11_PushVertexShaderUniforms(
|
||||||
|
@ -1073,7 +1504,9 @@ static void D3D11_QueueDestroyBuffer(
|
||||||
Refresh_Renderer* driverData,
|
Refresh_Renderer* driverData,
|
||||||
Refresh_Buffer* buffer
|
Refresh_Buffer* buffer
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11Buffer *d3dBuffer = (D3D11Buffer*) buffer;
|
||||||
|
ID3D11Buffer_Release(d3dBuffer->handle);
|
||||||
|
SDL_free(d3dBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void D3D11_QueueDestroyShaderModule(
|
static void D3D11_QueueDestroyShaderModule(
|
||||||
|
@ -1083,12 +1516,14 @@ static void D3D11_QueueDestroyShaderModule(
|
||||||
D3D11ShaderModule *d3dShaderModule = (D3D11ShaderModule*) shaderModule;
|
D3D11ShaderModule *d3dShaderModule = (D3D11ShaderModule*) shaderModule;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
/* Release the D3D11 shader objects and free the array */
|
/* Release the D3D11 shader objects and free the arrays */
|
||||||
for (i = 0; i < d3dShaderModule->numEntryPoints; i += 1)
|
for (i = 0; i < d3dShaderModule->numEntryPoints; i += 1)
|
||||||
{
|
{
|
||||||
ID3D11DeviceChild_Release(d3dShaderModule->shaders[i]);
|
ID3D11DeviceChild_Release(d3dShaderModule->shaders[i]);
|
||||||
|
ID3D10Blob_Release(d3dShaderModule->blobs[i]);
|
||||||
}
|
}
|
||||||
SDL_free(d3dShaderModule->shaders);
|
SDL_free(d3dShaderModule->shaders);
|
||||||
|
SDL_free(d3dShaderModule->blobs);
|
||||||
|
|
||||||
/* Destroy the SPIRV-Cross context.
|
/* Destroy the SPIRV-Cross context.
|
||||||
* This should destroy the entryPoints list as well.
|
* This should destroy the entryPoints list as well.
|
||||||
|
@ -1107,7 +1542,17 @@ static void D3D11_QueueDestroyGraphicsPipeline(
|
||||||
Refresh_Renderer* driverData,
|
Refresh_Renderer* driverData,
|
||||||
Refresh_GraphicsPipeline* graphicsPipeline
|
Refresh_GraphicsPipeline* graphicsPipeline
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
||||||
|
D3D11GraphicsPipeline *d3dGraphicsPipeline = (D3D11GraphicsPipeline*) graphicsPipeline;
|
||||||
|
|
||||||
|
ID3D11BlendState_Release(d3dGraphicsPipeline->colorAttachmentBlendState);
|
||||||
|
ID3D11DepthStencilState_Release(d3dGraphicsPipeline->depthStencilState);
|
||||||
|
ID3D11RasterizerState_Release(d3dGraphicsPipeline->rasterizerState);
|
||||||
|
ID3D11InputLayout_Release(d3dGraphicsPipeline->inputLayout);
|
||||||
|
|
||||||
|
/* FIXME: Release uniform buffers, once that's written in */
|
||||||
|
|
||||||
|
SDL_free(d3dGraphicsPipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Graphics State */
|
/* Graphics State */
|
||||||
|
@ -1201,7 +1646,31 @@ static void D3D11_BeginRenderPass(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Set viewport and scissor state */
|
/* Set default viewport and scissor state */
|
||||||
|
/* FIXME: Check how Vulkan sets these defaults */
|
||||||
|
viewports[0].TopLeftX = 0;
|
||||||
|
viewports[0].TopLeftY = 0;
|
||||||
|
viewports[0].Width = (float) ((D3D11Texture*) colorAttachmentInfos[0].texture)->twod.width;
|
||||||
|
viewports[0].Height = (float) ((D3D11Texture*) colorAttachmentInfos[0].texture)->twod.height;
|
||||||
|
viewports[0].MinDepth = 0; /* FIXME: Check what Vulkan does for these. */
|
||||||
|
viewports[0].MaxDepth = 1;
|
||||||
|
|
||||||
|
ID3D11DeviceContext_RSSetViewports(
|
||||||
|
cmdbuf->context,
|
||||||
|
1,
|
||||||
|
viewports
|
||||||
|
);
|
||||||
|
|
||||||
|
scissorRects[0].left = 0;
|
||||||
|
scissorRects[0].right = (LONG) viewports[0].Width;
|
||||||
|
scissorRects[0].top = 0;
|
||||||
|
scissorRects[0].bottom = (LONG) viewports[0].Height;
|
||||||
|
|
||||||
|
ID3D11DeviceContext_RSSetScissorRects(
|
||||||
|
cmdbuf->context,
|
||||||
|
1,
|
||||||
|
scissorRects
|
||||||
|
);
|
||||||
|
|
||||||
/* FIXME: What should we do with render area? */
|
/* FIXME: What should we do with render area? */
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1687,51 @@ static void D3D11_BindGraphicsPipeline(
|
||||||
Refresh_CommandBuffer* commandBuffer,
|
Refresh_CommandBuffer* commandBuffer,
|
||||||
Refresh_GraphicsPipeline* graphicsPipeline
|
Refresh_GraphicsPipeline* graphicsPipeline
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
||||||
|
D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer;
|
||||||
|
D3D11GraphicsPipeline *pipeline = (D3D11GraphicsPipeline*) graphicsPipeline;
|
||||||
|
|
||||||
|
ID3D11DeviceContext_OMSetBlendState(
|
||||||
|
cmdbuf->context,
|
||||||
|
pipeline->colorAttachmentBlendState,
|
||||||
|
pipeline->blendConstants,
|
||||||
|
0xffffffff
|
||||||
|
);
|
||||||
|
|
||||||
|
ID3D11DeviceContext_OMSetDepthStencilState(
|
||||||
|
cmdbuf->context,
|
||||||
|
pipeline->depthStencilState,
|
||||||
|
pipeline->stencilRef
|
||||||
|
);
|
||||||
|
|
||||||
|
ID3D11DeviceContext_IASetPrimitiveTopology(
|
||||||
|
cmdbuf->context,
|
||||||
|
pipeline->primitiveTopology
|
||||||
|
);
|
||||||
|
|
||||||
|
ID3D11DeviceContext_IASetInputLayout(
|
||||||
|
cmdbuf->context,
|
||||||
|
pipeline->inputLayout
|
||||||
|
);
|
||||||
|
|
||||||
|
ID3D11DeviceContext_RSSetState(
|
||||||
|
cmdbuf->context,
|
||||||
|
pipeline->rasterizerState
|
||||||
|
);
|
||||||
|
|
||||||
|
ID3D11DeviceContext_VSSetShader(
|
||||||
|
cmdbuf->context,
|
||||||
|
pipeline->vertexShader,
|
||||||
|
NULL,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
ID3D11DeviceContext_PSSetShader(
|
||||||
|
cmdbuf->context,
|
||||||
|
pipeline->fragmentShader,
|
||||||
|
NULL,
|
||||||
|
0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void D3D11_SetViewport(
|
static void D3D11_SetViewport(
|
||||||
|
@ -1245,7 +1758,32 @@ static void D3D11_BindVertexBuffers(
|
||||||
Refresh_Buffer** pBuffers,
|
Refresh_Buffer** pBuffers,
|
||||||
uint64_t* pOffsets
|
uint64_t* pOffsets
|
||||||
) {
|
) {
|
||||||
NOT_IMPLEMENTED
|
D3D11CommandBuffer *cmdbuf = (D3D11CommandBuffer*) commandBuffer;
|
||||||
|
ID3D11Buffer **buffers;
|
||||||
|
uint32_t *strides;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
buffers = SDL_stack_alloc(ID3D11Buffer*, bindingCount);
|
||||||
|
strides = SDL_stack_alloc(uint32_t, bindingCount);
|
||||||
|
for (i = 0; i < bindingCount; i += 1)
|
||||||
|
{
|
||||||
|
buffers[i] = ((D3D11Buffer*) pBuffers[i])->handle;
|
||||||
|
strides[i] = 20;
|
||||||
|
/* FIXME: Strides! Will probably need to get this from InputLayout somehow. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: State shadowing? */
|
||||||
|
ID3D11DeviceContext_IASetVertexBuffers(
|
||||||
|
cmdbuf->context,
|
||||||
|
firstBinding,
|
||||||
|
bindingCount,
|
||||||
|
buffers,
|
||||||
|
strides,
|
||||||
|
(const UINT*) pOffsets
|
||||||
|
);
|
||||||
|
|
||||||
|
SDL_stack_free(buffers);
|
||||||
|
SDL_stack_free(strides);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void D3D11_BindIndexBuffer(
|
static void D3D11_BindIndexBuffer(
|
||||||
|
|
Loading…
Reference in New Issue