Skip to content

Commit

Permalink
amd_ags_x64: Implement multi draw instanced indirect count functions.
Browse files Browse the repository at this point in the history
CW-Bug-Id: #22976
  • Loading branch information
Paul Gofman committed Feb 22, 2024
1 parent 000724f commit 6861e8c
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 2 deletions.
4 changes: 2 additions & 2 deletions dlls/amd_ags_x64/amd_ags_x64.spec
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
@ stub agsDriverExtensionsDX11_IASetPrimitiveTopology
@ stdcall agsDriverExtensionsDX11_Init(ptr ptr long ptr)
@ stdcall -norelay -arch=win64 agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirect() DX11_MultiDrawIndexedInstancedIndirect_impl
@ stub agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect
@ stdcall -norelay -arch=win64 agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect() DX11_MultiDrawIndexedInstancedIndirectCountIndirect_impl
@ stdcall -norelay -arch=win64 agsDriverExtensionsDX11_MultiDrawInstancedIndirect() DX11_MultiDrawInstancedIndirect_impl
@ stub agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect
@ stdcall -norelay -arch=win64 agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect() DX11_MultiDrawInstancedIndirectCountIndirect_impl
@ stub agsDriverExtensionsDX11_NotifyResourceBeginAllAccess
@ stub agsDriverExtensionsDX11_NotifyResourceEndAllAccess
@ stub agsDriverExtensionsDX11_NotifyResourceEndWrites
Expand Down
130 changes: 130 additions & 0 deletions dlls/amd_ags_x64/amd_ags_x64_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,7 @@ static void get_dx11_extensions_supported(ID3D11Device *device, AGSDX11Extension
extensions->depthBoundsTest = !!ID3D11VkExtDevice_GetExtensionSupport(ext_device, D3D11_VK_EXT_DEPTH_BOUNDS);
extensions->uavOverlap = !!ID3D11VkExtDevice_GetExtensionSupport(ext_device, D3D11_VK_EXT_BARRIER_CONTROL);
extensions->multiDrawIndirect = !!ID3D11VkExtDevice_GetExtensionSupport(ext_device, D3D11_VK_EXT_MULTI_DRAW_INDIRECT);
extensions->multiDrawIndirectCountIndirect = !!ID3D11VkExtDevice_GetExtensionSupport(ext_device, D3D11_VK_EXT_MULTI_DRAW_INDIRECT_COUNT);
extensions->UAVOverlapDeferredContexts = extensions->uavOverlap;

ID3D11VkExtDevice_Release(ext_device);
Expand Down Expand Up @@ -1589,6 +1590,135 @@ __ASM_GLOBAL_FUNC( DX11_MultiDrawInstancedIndirect_impl,
"jmp " __ASM_NAME("agsDriverExtensionsDX11_MultiDrawInstancedIndirect_520") "\n\t"
"1:\tjmp " __ASM_NAME("agsDriverExtensionsDX11_MultiDrawInstancedIndirect") )

static unsigned int get_max_draw_count(ID3D11Buffer *args, unsigned int offset, unsigned int stride, unsigned int size)
{
D3D11_BUFFER_DESC desc;
unsigned int count;

ID3D11Buffer_GetDesc(args, &desc);
if (offset >= desc.ByteWidth)
{
WARN("offset %u, buffer size %u.\n", offset, desc.ByteWidth);
return 0;
}
count = (desc.ByteWidth - offset) / stride;
if (desc.ByteWidth - offset - count * stride >= size)
++count;
if (!count)
WARN("zero count, buffer size %u, offset %u, stride %u, size %u.\n", desc.ByteWidth, offset, stride, size);
return count;
}

AGSReturnCode WINAPI agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect(AGSContext *context, ID3D11DeviceContext *dx_context,
ID3D11Buffer *buffer_for_draw_count, unsigned int aligned_byte_offset_for_draw_count, ID3D11Buffer *buffer_for_args,
unsigned int aligned_byte_offset_for_args, unsigned int byte_stride_for_args)
{
ID3D11VkExtContext *ext_context;
unsigned int max_draw_count;

TRACE("context %p, dx_context %p, count buffer %p, offset %u, args buffer %p, offset %u, stride %u.\n",
context, dx_context, buffer_for_draw_count, aligned_byte_offset_for_draw_count, buffer_for_args,
aligned_byte_offset_for_args, byte_stride_for_args);

if (!context || !dx_context)
{
WARN("Invalid arguments.\n");
return AGS_INVALID_ARGS;
}

if (!context->extensions.multiDrawIndirectCountIndirect)
return AGS_EXTENSION_NOT_SUPPORTED;

if (FAILED(ID3D11DeviceContext_QueryInterface(dx_context, &IID_ID3D11VkExtContext, (void **)&ext_context)))
{
TRACE("No ID3D11VkExtContext.\n");
return AGS_EXTENSION_NOT_SUPPORTED;
}

max_draw_count = get_max_draw_count(buffer_for_args, aligned_byte_offset_for_args, byte_stride_for_args, sizeof(D3D11_DRAW_INDEXED_INSTANCED_INDIRECT_ARGS));
ID3D11VkExtContext_MultiDrawIndexedIndirectCount(ext_context, max_draw_count, buffer_for_draw_count, aligned_byte_offset_for_draw_count,
buffer_for_args, aligned_byte_offset_for_args, byte_stride_for_args);
ID3D11VkExtContext_Release(ext_context);
return AGS_SUCCESS;
}

AGSReturnCode WINAPI agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect_520(AGSContext *context,
ID3D11Buffer *buffer_for_draw_count, unsigned int aligned_byte_offset_for_draw_count, ID3D11Buffer *buffer_for_args,
unsigned int aligned_byte_offset_for_args, unsigned int byte_stride_for_args)
{
if (!context || !context->d3d11_context)
{
WARN("Invalid arguments.\n");
return AGS_INVALID_ARGS;
}
return agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect(context, context->d3d11_context,
buffer_for_draw_count, aligned_byte_offset_for_draw_count,
buffer_for_args, aligned_byte_offset_for_args, byte_stride_for_args);
}

C_ASSERT(AMD_AGS_VERSION_5_3_0 == 4);
__ASM_GLOBAL_FUNC( DX11_MultiDrawIndexedInstancedIndirectCountIndirect_impl,
"mov (%rcx),%eax\n\t" /* version */
"cmp $4,%eax\n\t"
"jge 1f\n\t"
"jmp " __ASM_NAME("agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect_520") "\n\t"
"1:\tjmp " __ASM_NAME("agsDriverExtensionsDX11_MultiDrawIndexedInstancedIndirectCountIndirect") )


AGSReturnCode WINAPI agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect(AGSContext *context, ID3D11DeviceContext *dx_context,
ID3D11Buffer *buffer_for_draw_count, unsigned int aligned_byte_offset_for_draw_count, ID3D11Buffer *buffer_for_args,
unsigned int aligned_byte_offset_for_args, unsigned int byte_stride_for_args)
{
ID3D11VkExtContext *ext_context;
unsigned int max_draw_count;

TRACE("context %p, dx_context %p, count buffer %p, offset %u, args buffer %p, offset %u, stride %u.\n",
context, dx_context, buffer_for_draw_count, aligned_byte_offset_for_draw_count, buffer_for_args,
aligned_byte_offset_for_args, byte_stride_for_args);

if (!context || !dx_context)
{
WARN("Invalid arguments.\n");
return AGS_INVALID_ARGS;
}

if (!context->extensions.multiDrawIndirectCountIndirect)
return AGS_EXTENSION_NOT_SUPPORTED;

if (FAILED(ID3D11DeviceContext_QueryInterface(dx_context, &IID_ID3D11VkExtContext, (void **)&ext_context)))
{
TRACE("No ID3D11VkExtContext.\n");
return AGS_EXTENSION_NOT_SUPPORTED;
}

max_draw_count = get_max_draw_count(buffer_for_args, aligned_byte_offset_for_args, byte_stride_for_args, sizeof(D3D11_DRAW_INSTANCED_INDIRECT_ARGS));
ID3D11VkExtContext_MultiDrawIndirectCount(ext_context, max_draw_count, buffer_for_draw_count, aligned_byte_offset_for_draw_count,
buffer_for_args, aligned_byte_offset_for_args, byte_stride_for_args);
ID3D11VkExtContext_Release(ext_context);
return AGS_SUCCESS;
}

AGSReturnCode WINAPI agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect_520(AGSContext *context,
ID3D11Buffer *buffer_for_draw_count, unsigned int aligned_byte_offset_for_draw_count, ID3D11Buffer *buffer_for_args,
unsigned int aligned_byte_offset_for_args, unsigned int byte_stride_for_args)
{
if (!context || !context->d3d11_context)
{
WARN("Invalid arguments.\n");
return AGS_INVALID_ARGS;
}
return agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect(context, context->d3d11_context,
buffer_for_draw_count, aligned_byte_offset_for_draw_count,
buffer_for_args, aligned_byte_offset_for_args, byte_stride_for_args);
}

C_ASSERT(AMD_AGS_VERSION_5_3_0 == 4);
__ASM_GLOBAL_FUNC( DX11_MultiDrawInstancedIndirectCountIndirect_impl,
"mov (%rcx),%eax\n\t" /* version */
"cmp $4,%eax\n\t"
"jge 1f\n\t"
"jmp " __ASM_NAME("agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect_520") "\n\t"
"1:\tjmp " __ASM_NAME("agsDriverExtensionsDX11_MultiDrawInstancedIndirectCountIndirect") )

AGSReturnCode WINAPI agsDriverExtensionsDX11_DestroyDevice_520(AGSContext *context, ID3D11Device* device,
unsigned int *device_ref, ID3D11DeviceContext *device_context,
Expand Down

0 comments on commit 6861e8c

Please sign in to comment.