First rough draft of Compute functions (untested!)

d3d11
Caleb Cornett 2024-02-07 21:03:21 -06:00 committed by cosmonaut
parent f598b65be5
commit 297b8b2cd2
1 changed files with 207 additions and 6 deletions

View File

@ -361,6 +361,7 @@ typedef struct D3D11Texture
ID3D11Resource *handle; /* ID3D11Texture2D* or ID3D11Texture3D* */ ID3D11Resource *handle; /* ID3D11Texture2D* or ID3D11Texture3D* */
ID3D11ShaderResourceView *shaderView; ID3D11ShaderResourceView *shaderView;
ID3D11View *targetView; /* ID3D11RenderTargetView* or ID3D11DepthStencilView* */ ID3D11View *targetView; /* ID3D11RenderTargetView* or ID3D11DepthStencilView* */
ID3D11UnorderedAccessView *unorderedAccessView;
/* Basic Info */ /* Basic Info */
Refresh_TextureFormat format; Refresh_TextureFormat format;
@ -420,11 +421,20 @@ typedef struct D3D11GraphicsPipeline
uint32_t fragmentUniformBlockSize; uint32_t fragmentUniformBlockSize;
} D3D11GraphicsPipeline; } D3D11GraphicsPipeline;
typedef struct D3D11ComputePipeline
{
ID3D11ComputeShader *computeShader;
uint64_t computeUniformBlockSize;
uint32_t numTextures;
uint32_t numBuffers;
} D3D11ComputePipeline;
typedef struct D3D11Buffer typedef struct D3D11Buffer
{ {
ID3D11Buffer *handle; ID3D11Buffer *handle;
uint32_t size; uint32_t size;
uint8_t isDynamic; uint8_t isDynamic;
ID3D11UnorderedAccessView *uav;
} D3D11Buffer; } D3D11Buffer;
typedef struct D3D11UniformBuffer typedef struct D3D11UniformBuffer
@ -444,6 +454,9 @@ typedef struct D3D11CommandBuffer
ID3D11DepthStencilView *dsView; ID3D11DepthStencilView *dsView;
D3D11GraphicsPipeline *graphicsPipeline; D3D11GraphicsPipeline *graphicsPipeline;
/* Compute Pass */
D3D11ComputePipeline *computePipeline;
/* State */ /* State */
SDL_threadID threadID; SDL_threadID threadID;
ID3D11Query *completionQuery; ID3D11Query *completionQuery;
@ -451,6 +464,7 @@ typedef struct D3D11CommandBuffer
/* Uniforms */ /* Uniforms */
D3D11UniformBuffer *vertexUniformBuffer; D3D11UniformBuffer *vertexUniformBuffer;
D3D11UniformBuffer *fragmentUniformBuffer; D3D11UniformBuffer *fragmentUniformBuffer;
D3D11UniformBuffer *computeUniformBuffer;
D3D11UniformBuffer **boundUniformBuffers; D3D11UniformBuffer **boundUniformBuffers;
uint32_t boundUniformBufferCount; uint32_t boundUniformBufferCount;
@ -830,7 +844,28 @@ static void D3D11_DispatchCompute(
uint32_t groupCountZ, uint32_t groupCountZ,
uint32_t computeParamOffset uint32_t computeParamOffset
) { ) {
NOT_IMPLEMENTED D3D11CommandBuffer* d3d11CommandBuffer = (D3D11CommandBuffer*)commandBuffer;
uint32_t computeOffsetInConstants = computeParamOffset / 16;
uint32_t computeBlockSizeInConstants = (uint32_t) (d3d11CommandBuffer->computePipeline->computeUniformBlockSize / 16);
if (d3d11CommandBuffer->computeUniformBuffer != NULL)
{
ID3D11DeviceContext1_CSSetConstantBuffers1(
d3d11CommandBuffer->context,
0,
1,
&d3d11CommandBuffer->computeUniformBuffer->d3d11Buffer->handle,
&computeOffsetInConstants,
&computeBlockSizeInConstants
);
}
ID3D11DeviceContext_Dispatch(
d3d11CommandBuffer->context,
groupCountX,
groupCountY,
groupCountZ
);
} }
/* State Creation */ /* State Creation */
@ -1064,8 +1099,16 @@ static Refresh_ComputePipeline* D3D11_CreateComputePipeline(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_ComputeShaderInfo *computeShaderInfo Refresh_ComputeShaderInfo *computeShaderInfo
) { ) {
NOT_IMPLEMENTED D3D11Renderer* renderer = (D3D11Renderer*) driverData;
return NULL; D3D11ComputePipeline* pipeline = (D3D11ComputePipeline*) SDL_malloc(sizeof(D3D11ComputePipeline));
D3D11ShaderModule* shaderModule = (D3D11ShaderModule*) computeShaderInfo->shaderModule;
pipeline->computeShader = (ID3D11ComputeShader*) shaderModule->shader;
pipeline->numTextures = computeShaderInfo->imageBindingCount;
pipeline->numBuffers = computeShaderInfo->bufferBindingCount;
pipeline->computeUniformBlockSize = computeShaderInfo->uniformBufferSize;
return (Refresh_ComputePipeline*) pipeline;
} }
static inline uint32_t D3D11_INTERNAL_NextHighestAlignment( static inline uint32_t D3D11_INTERNAL_NextHighestAlignment(
@ -1318,6 +1361,7 @@ static Refresh_Texture* D3D11_CreateTexture(
ID3D11ShaderResourceView *srv = NULL; ID3D11ShaderResourceView *srv = NULL;
ID3D11RenderTargetView *rtv = NULL; ID3D11RenderTargetView *rtv = NULL;
ID3D11DepthStencilView *dsv = NULL; ID3D11DepthStencilView *dsv = NULL;
ID3D11UnorderedAccessView *uav = NULL;
D3D11Texture *d3d11Texture; D3D11Texture *d3d11Texture;
HRESULT res; HRESULT res;
@ -1404,6 +1448,32 @@ static Refresh_Texture* D3D11_CreateTexture(
return NULL; return NULL;
} }
} }
/* Create the UAV, if applicable */
if (isCompute)
{
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = desc2D.Format;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
uavDesc.Texture2D.MipSlice = 0; /* FIXME: Is this right? */
res = ID3D11Device_CreateUnorderedAccessView(
renderer->device,
textureHandle,
&uavDesc,
&uav
);
if (FAILED(res))
{
ID3D11Resource_Release(textureHandle);
if (srv != NULL)
{
ID3D11ShaderResourceView_Release(srv);
}
D3D11_INTERNAL_LogError(renderer->device, "Could not create UAV for 2D texture", res);
return NULL;
}
}
} }
else else
{ {
@ -1460,6 +1530,33 @@ static Refresh_Texture* D3D11_CreateTexture(
return NULL; return NULL;
} }
} }
/* Create the UAV, if applicable */
if (isCompute)
{
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
uavDesc.Texture3D.MipSlice = 0;
uavDesc.Texture3D.FirstWSlice = 0; /* FIXME */
uavDesc.Texture3D.WSize = 0; /* FIXME */
res = ID3D11Device_CreateUnorderedAccessView(
renderer->device,
textureHandle,
&uavDesc,
&uav
);
if (FAILED(res))
{
ID3D11Resource_Release(textureHandle);
if (srv != NULL)
{
ID3D11ShaderResourceView_Release(srv);
}
D3D11_INTERNAL_LogError(renderer->device, "Could not create UAV for 3D texture", res);
return NULL;
}
}
} }
/* Create the RTV or DSV, if applicable */ /* Create the RTV or DSV, if applicable */
@ -1482,6 +1579,7 @@ static Refresh_Texture* D3D11_CreateTexture(
d3d11Texture->isCube = textureCreateInfo->isCube; d3d11Texture->isCube = textureCreateInfo->isCube;
d3d11Texture->targetView = isRenderTarget ? (ID3D11View*) rtv : (ID3D11View*) dsv; d3d11Texture->targetView = isRenderTarget ? (ID3D11View*) rtv : (ID3D11View*) dsv;
d3d11Texture->shaderView = srv; d3d11Texture->shaderView = srv;
d3d11Texture->unorderedAccessView = uav;
return (Refresh_Texture*) d3d11Texture; return (Refresh_Texture*) d3d11Texture;
} }
@ -1494,6 +1592,7 @@ static Refresh_Buffer* D3D11_CreateBuffer(
D3D11Renderer *renderer = (D3D11Renderer*) driverData; D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11_BUFFER_DESC bufferDesc; D3D11_BUFFER_DESC bufferDesc;
ID3D11Buffer *bufferHandle; ID3D11Buffer *bufferHandle;
ID3D11UnorderedAccessView *uav = NULL;
D3D11Buffer *d3d11Buffer; D3D11Buffer *d3d11Buffer;
HRESULT res; HRESULT res;
@ -1528,10 +1627,34 @@ static Refresh_Buffer* D3D11_CreateBuffer(
); );
ERROR_CHECK_RETURN("Could not create buffer", NULL); ERROR_CHECK_RETURN("Could not create buffer", NULL);
/* Create a UAV for the buffer */
if (usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT)
{
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = DXGI_FORMAT_R8_UINT;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = 0;
uavDesc.Buffer.NumElements = sizeInBytes;
res = ID3D11Device_CreateUnorderedAccessView(
renderer->device,
(ID3D11Resource*) bufferHandle,
&uavDesc,
&uav
);
if (FAILED(res))
{
ID3D11Buffer_Release(bufferHandle);
ERROR_CHECK_RETURN("Could not create UAV for buffer!", NULL);
}
}
d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer)); d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer));
d3d11Buffer->handle = bufferHandle; d3d11Buffer->handle = bufferHandle;
d3d11Buffer->size = sizeInBytes; d3d11Buffer->size = sizeInBytes;
d3d11Buffer->isDynamic = isDynamic; d3d11Buffer->isDynamic = isDynamic;
d3d11Buffer->uav = uav;
return (Refresh_Buffer*) d3d11Buffer; return (Refresh_Buffer*) d3d11Buffer;
} }
@ -1979,6 +2102,10 @@ static void D3D11_QueueDestroyTexture(
{ {
ID3D11View_Release(d3d11Texture->targetView); ID3D11View_Release(d3d11Texture->targetView);
} }
if (d3d11Texture->unorderedAccessView)
{
ID3D11UnorderedAccessView_Release(d3d11Texture->unorderedAccessView);
}
ID3D11Resource_Release(d3d11Texture->handle); ID3D11Resource_Release(d3d11Texture->handle);
@ -1999,7 +2126,14 @@ static void D3D11_QueueDestroyBuffer(
Refresh_Buffer *buffer Refresh_Buffer *buffer
) { ) {
D3D11Buffer *d3d11Buffer = (D3D11Buffer*) buffer; D3D11Buffer *d3d11Buffer = (D3D11Buffer*) buffer;
if (d3d11Buffer->uav)
{
ID3D11UnorderedAccessView_Release(d3d11Buffer->handle);
}
ID3D11Buffer_Release(d3d11Buffer->handle); ID3D11Buffer_Release(d3d11Buffer->handle);
SDL_free(d3d11Buffer); SDL_free(d3d11Buffer);
} }
@ -2138,8 +2272,10 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
commandBuffer->threadID = SDL_ThreadID(); commandBuffer->threadID = SDL_ThreadID();
commandBuffer->swapchainData = NULL; commandBuffer->swapchainData = NULL;
commandBuffer->graphicsPipeline = NULL; commandBuffer->graphicsPipeline = NULL;
commandBuffer->computePipeline = NULL;
commandBuffer->vertexUniformBuffer = NULL; commandBuffer->vertexUniformBuffer = NULL;
commandBuffer->fragmentUniformBuffer = NULL; commandBuffer->fragmentUniformBuffer = NULL;
commandBuffer->computeUniformBuffer = NULL;
commandBuffer->dsView = NULL; commandBuffer->dsView = NULL;
for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) for (i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{ {
@ -2487,7 +2623,38 @@ static void D3D11_BindComputePipeline(
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_ComputePipeline *computePipeline Refresh_ComputePipeline *computePipeline
) { ) {
NOT_IMPLEMENTED D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
D3D11ComputePipeline *pipeline = (D3D11ComputePipeline*) computePipeline;
d3d11CommandBuffer->computePipeline = pipeline;
if (d3d11CommandBuffer->computeUniformBuffer != NULL)
{
D3D11_INTERNAL_BindUniformBuffer(
d3d11CommandBuffer,
d3d11CommandBuffer->computeUniformBuffer
);
}
if (pipeline->computeUniformBlockSize == 0)
{
d3d11CommandBuffer->computeUniformBuffer = NULL;
}
else
{
d3d11CommandBuffer->computeUniformBuffer = D3D11_INTERNAL_AcquireUniformBufferFromPool(
renderer,
pipeline->computeUniformBlockSize
);
}
ID3D11DeviceContext_CSSetShader(
d3d11CommandBuffer->context,
pipeline->computeShader,
NULL,
0
);
} }
static void D3D11_BindComputeBuffers( static void D3D11_BindComputeBuffers(
@ -2495,7 +2662,24 @@ static void D3D11_BindComputeBuffers(
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Buffer **pBuffers Refresh_Buffer **pBuffers
) { ) {
NOT_IMPLEMENTED D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
ID3D11UnorderedAccessView* uavs[MAX_BUFFER_BINDINGS]; /* FIXME: Is this limit right? */
int32_t numBuffers = d3d11CommandBuffer->computePipeline->numBuffers;
for (int32_t i = 0; i < numBuffers; i += 1)
{
uavs[i] = ((D3D11Buffer*) pBuffers[i])->uav;
}
ID3D11DeviceContext_CSSetUnorderedAccessViews(
d3d11CommandBuffer->context,
0,
numBuffers,
uavs,
NULL
);
} }
static void D3D11_BindComputeTextures( static void D3D11_BindComputeTextures(
@ -2503,7 +2687,24 @@ static void D3D11_BindComputeTextures(
Refresh_CommandBuffer *commandBuffer, Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures Refresh_Texture **pTextures
) { ) {
NOT_IMPLEMENTED D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
ID3D11UnorderedAccessView *uavs[MAX_TEXTURE_SAMPLERS]; /* FIXME: Is this limit right? */
int32_t numTextures = d3d11CommandBuffer->computePipeline->numTextures;
for (int32_t i = 0; i < numTextures; i += 1)
{
uavs[i] = ((D3D11Texture*) pTextures[i])->unorderedAccessView;
}
ID3D11DeviceContext_CSSetUnorderedAccessViews(
d3d11CommandBuffer->context,
0,
numTextures,
uavs,
NULL
);
} }
/* Window and Swapchain Management */ /* Window and Swapchain Management */