restructure binding APIs
continuous-integration/drone/push Build is passing Details

pull/51/head
cosmonaut 2024-03-01 12:39:33 -08:00
parent eeccea8ce8
commit b64bf06c7b
4 changed files with 470 additions and 379 deletions

View File

@ -333,11 +333,11 @@ typedef enum Refresh_TransferOptions
REFRESH_TRANSFEROPTIONS_OVERWRITE
} Refresh_TransferOptions;
typedef enum Refresh_CopyOptions
typedef enum Refresh_WriteOptions
{
REFRESH_COPYOPTIONS_SAFEDISCARD,
REFRESH_COPYOPTIONS_SAFEOVERWRITE
} Refresh_CopyOptions;
REFRESH_WRITEOPTIONS_SAFEDISCARD,
REFRESH_WRITEOPTIONS_SAFEOVERWRITE
} Refresh_WriteOptions;
typedef enum Refresh_Backend
{
@ -583,26 +583,91 @@ typedef struct Refresh_GraphicsPipelineCreateInfo
/* Render pass structures */
/* These structures define how textures will be read/written in a render pass.
*
* loadOp: Determines what is done with the texture slice at the beginning of the render pass.
*
* LOAD:
* Loads the texture slice.
*
* CLEAR:
* Clears the texture slice to a single color.
*
* DONT_CARE:
* The driver will do whatever it wants with the texture slice memory.
* This is a good option if you know that every single pixel will be touched in the render pass.
*
* storeOp: Determines what is done with the texture slice at the end of the render pass.
*
* STORE:
* Stores the results of the render pass in the texture slice.
*
* DONT_CARE:
* The driver will do whatever it wants with the texture slice memory.
* This is often a good option for depth/stencil textures.
*
*
* writeOption is ignored if loadOp is LOAD and is implicitly assumed to be SAFEOVERWRITE.
* Interleaving LOAD and SAFEDISCARD successively on the same texture (not slice!) is undefined behavior.
*
* writeOption:
* SAFEDISCARD:
* If this texture slice has been used in commands that have not completed,
* those commands will still be valid at the cost of increased memory usage.
* You may NOT assume that any of the previous texture data is retained.
* If the texture slice was not in use, this option is equivalent to SAFEOVERWRITE.
* This is a good option to prevent stalls when frequently reusing a texture slice in rendering.
*
* SAFEOVERWRITE:
* Overwrites the data safely using a GPU memory barrier.
*/
typedef struct Refresh_ColorAttachmentInfo
{
Refresh_TextureSlice textureSlice;
Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */
Refresh_Vec4 clearColor; /* Can be ignored by RenderPass if CLEAR is not used */
Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp;
uint8_t safeDiscard; /* ignored if loadOp is LOAD */
Refresh_WriteOptions writeOption;
} Refresh_ColorAttachmentInfo;
typedef struct Refresh_DepthStencilAttachmentInfo
{
Refresh_TextureSlice textureSlice;
Refresh_DepthStencilValue depthStencilClearValue; /* Can be ignored by RenderPass */
Refresh_DepthStencilValue depthStencilClearValue; /* Can be ignored by RenderPass if CLEAR is not used */
Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp;
Refresh_LoadOp stencilLoadOp;
Refresh_StoreOp stencilStoreOp;
uint8_t safeDiscard; /* ignored if either loadOp or stencilLoadOp is LOAD*/
Refresh_WriteOptions writeOption;
} Refresh_DepthStencilAttachmentInfo;
/* Binding structs */
typedef struct Refresh_BufferBinding
{
Refresh_GpuBuffer *gpuBuffer;
uint32_t offset;
} Refresh_BufferBinding;
typedef struct Refresh_TextureSamplerBinding
{
Refresh_Texture *texture;
Refresh_Sampler *sampler;
} Refresh_TextureSamplerBinding;
typedef struct Refresh_ComputeBufferBinding
{
Refresh_GpuBuffer *gpuBuffer;
Refresh_WriteOptions writeOption;
} Refresh_ComputeBufferBinding;
typedef struct Refresh_ComputeTextureBinding
{
Refresh_TextureSlice textureSlice;
Refresh_WriteOptions writeOption;
} Refresh_ComputeTextureBinding;
/* Functions */
/* Logging */
@ -828,49 +893,43 @@ REFRESHAPI void Refresh_BindVertexBuffers(
Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
Refresh_GpuBuffer **pBuffers,
uint64_t *pOffsets
Refresh_BufferBinding *pBindings
);
/* Binds an index buffer for use with subsequent draw calls. */
REFRESHAPI void Refresh_BindIndexBuffer(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer *gpuBuffer,
uint64_t offset,
Refresh_BufferBinding *pBinding,
Refresh_IndexElementSize indexElementSize
);
/* Sets textures/samplers for use with the currently bound vertex shader.
*
* NOTE:
* The length of the passed arrays must be equal to the number
* The length of the bindings array must be equal to the number
* of sampler bindings specified by the pipeline.
*
* textures: A pointer to an array of textures.
* samplers: A pointer to an array of samplers.
* pBindings: A pointer to an array of TextureSamplerBindings.
*/
REFRESHAPI void Refresh_BindVertexSamplers(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
Refresh_TextureSamplerBinding *pBindings
);
/* Sets textures/samplers for use with the currently bound fragment shader.
*
* NOTE:
* The length of the passed arrays must be equal to the number
* The length of the bindings array must be equal to the number
* of sampler bindings specified by the pipeline.
*
* textures: A pointer to an array of textures.
* samplers: A pointer to an array of samplers.
* pBindings: A pointer to an array of TextureSamplerBindings.
*/
REFRESHAPI void Refresh_BindFragmentSamplers(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
Refresh_TextureSamplerBinding *pBindings
);
/* Pushes vertex shader uniforms to the device.
@ -991,26 +1050,28 @@ REFRESHAPI void Refresh_BindComputePipeline(
/* Binds buffers for use with the currently bound compute pipeline.
*
* pBuffers: An array of buffers to bind.
* pBindings:
* An array of ComputeBufferBinding structs.
* Length must be equal to the number of buffers
* specified by the compute pipeline.
*/
REFRESHAPI void Refresh_BindComputeBuffers(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer **pBuffers
Refresh_ComputeBufferBinding *pBindings
);
/* Binds textures for use with the currently bound compute pipeline.
*
* pTextureSlices: An array of texture slices to bind.
* Length must be equal to the number of buffers
* pBindings:
* An array of ComputeTextureBinding structs.
* Length must be equal to the number of textures
* specified by the compute pipeline.
*/
REFRESHAPI void Refresh_BindComputeTextures(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice **pTextureSlices
Refresh_ComputeTextureBinding *pBindings
);
/* Pushes compute shader params to the device.
@ -1054,15 +1115,17 @@ REFRESHAPI void Refresh_EndComputePass(
/* Immediately copies data from a pointer into a TransferBuffer.
*
* option:
* transferOption:
* SAFEDISCARD:
* If this TransferBuffer has been used in a copy command that has not completed,
* the issued copy commands will still be valid at the cost of increased memory usage.
* Otherwise the data will overwrite.
* If this TransferBuffer has been used in commands that have not completed,
* the issued commands will still be valid at the cost of increased memory usage.
* You may NOT assume that any of the previous data is retained.
* If the TransferBuffer was not in use, this option is equivalent to OVERWRITE.
* This is a good option to prevent stalls when frequently updating data.
* It is not recommended to use this option with large TransferBuffers.
*
* OVERWRITE:
* Overwrites the data regardless of whether a copy has been issued.
* Overwrites the data regardless of whether a command has been issued.
* Use this option with great care, as it can cause data races to occur!
*/
REFRESHAPI void Refresh_SetTransferData(
@ -1070,7 +1133,7 @@ REFRESHAPI void Refresh_SetTransferData(
void* data,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
);
/* Immediately copies data from a TransferBuffer into a pointer. */
@ -1095,16 +1158,17 @@ REFRESHAPI void Refresh_BeginCopyPass(
*/
/*
* option:
* writeOption:
* SAFEDISCARD:
* If this TransferBuffer has been used in a copy command that has not completed,
* the issued copy commands will still be valid at the cost of increased memory usage.
* Otherwise the data will overwrite.
* If the destination resource has been used in commands that have not completed,
* the issued commands will still be valid at the cost of increased memory usage.
* You may NOT assume that any of the previous data is retained.
* If the destination resource was not in use, this option is equivalent to SAFEOVERWRITE.
* This is a good option to prevent stalls on resources with frequent updates.
* It is not recommended to use this option with large resources.
*
* OVERWRITE:
* Overwrites the data regardless of whether a copy has been issued.
* Use this option with great care, as it can cause data races to occur!
* SAFEOVERWRITE:
* Overwrites the data safely using a GPU memory barrier.
*/
/* Uploads data from a TransferBuffer to a texture. */
@ -1114,7 +1178,7 @@ REFRESHAPI void Refresh_UploadToTexture(
Refresh_TransferBuffer *transferBuffer,
Refresh_TextureRegion *textureRegion,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
/* Uploads data from a TransferBuffer to a GpuBuffer. */
@ -1124,7 +1188,7 @@ REFRESHAPI void Refresh_UploadToBuffer(
Refresh_TransferBuffer *transferBuffer,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
/* GPU-to-CPU copies occur on the GPU timeline.
@ -1133,6 +1197,20 @@ REFRESHAPI void Refresh_UploadToBuffer(
* until the command buffer has finished execution.
*/
/*
* transferOption:
* SAFEDISCARD:
* If this TransferBuffer has been used in commands that have not completed,
* the issued commands will still be valid at the cost of increased memory usage.
* You may NOT assume that any of the previous data is retained.
* If the TransferBuffer was not in use, this option is equivalent to OVERWRITE.
* It is not recommended to use this option with large TransferBuffers.
*
* OVERWRITE:
* Overwrites the data regardless of whether a command has been issued.
* Use this option with great care, as it can cause data races to occur!
*/
/* Downloads data from a texture to a TransferBuffer. */
REFRESHAPI void Refresh_DownloadFromTexture(
Refresh_Device *device,
@ -1140,7 +1218,7 @@ REFRESHAPI void Refresh_DownloadFromTexture(
Refresh_TextureRegion *textureRegion,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferImageCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
);
/* Downloads data from a GpuBuffer object. */
@ -1150,7 +1228,7 @@ REFRESHAPI void Refresh_DownloadFromBuffer(
Refresh_GpuBuffer *gpuBuffer,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
);
/* GPU-to-GPU copies occur on the GPU timeline,
@ -1158,18 +1236,17 @@ REFRESHAPI void Refresh_DownloadFromBuffer(
*/
/*
* option:
* writeOption:
* SAFEDISCARD:
* If the destination resource has been used in a copy command that has not completed,
* the issued copy commands will still be valid at the cost of increased memory usage.
* Otherwise the data will safely overwrite.
* If the destination resource has been used in commands that have not completed,
* the issued commands will still be valid at the cost of increased memory usage.
* You may NOT assume that any of the previous data is retained.
* If the destination resource was not in use, this option is equivalent to SAFEOVERWRITE.
* This is a good option to prevent stalls on resources with frequent updates.
* It is not recommended to use this option with large resources.
*
* SAFEOVERWRITE:
* Overwrites the data regardless of whether a copy has been issued.
* This will insert a memory barrier, so it could cause suboptimal performance compared to SAFEDISCARD
* on resources that update frequently across submissions.
* Overwrites the data safely using a GPU memory barrier.
*/
/* Performs a texture-to-texture copy. */
@ -1178,7 +1255,7 @@ REFRESHAPI void Refresh_CopyTextureToTexture(
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureRegion *source,
Refresh_TextureRegion *destination,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
/* Copies image data from a texture slice into a buffer. */
@ -1188,7 +1265,7 @@ REFRESHAPI void Refresh_CopyTextureToBuffer(
Refresh_TextureRegion *textureRegion,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
/* Copies data from a buffer to a texture slice. */
@ -1198,7 +1275,7 @@ REFRESHAPI void Refresh_CopyBufferToTexture(
Refresh_GpuBuffer *gpuBuffer,
Refresh_TextureRegion *textureRegion,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
/* Copies data from a buffer to a buffer. */
@ -1208,7 +1285,7 @@ REFRESHAPI void Refresh_CopyBufferToBuffer(
Refresh_GpuBuffer *source,
Refresh_GpuBuffer *destination,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
/* Generate mipmaps for the given texture. */

View File

@ -461,8 +461,7 @@ void Refresh_BindVertexBuffers(
Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
Refresh_GpuBuffer **pBuffers,
uint64_t *pOffsets
Refresh_BufferBinding *pBindings
) {
NULL_RETURN(device);
device->BindVertexBuffers(
@ -470,24 +469,21 @@ void Refresh_BindVertexBuffers(
commandBuffer,
firstBinding,
bindingCount,
pBuffers,
pOffsets
pBindings
);
}
void Refresh_BindIndexBuffer(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer *gpuBuffer,
uint64_t offset,
Refresh_BufferBinding *pBinding,
Refresh_IndexElementSize indexElementSize
) {
NULL_RETURN(device);
device->BindIndexBuffer(
device->driverData,
commandBuffer,
gpuBuffer,
offset,
pBinding,
indexElementSize
);
}
@ -495,30 +491,26 @@ void Refresh_BindIndexBuffer(
void Refresh_BindVertexSamplers(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
Refresh_TextureSamplerBinding *pBindings
) {
NULL_RETURN(device);
device->BindVertexSamplers(
device->driverData,
commandBuffer,
pTextures,
pSamplers
pBindings
);
}
void Refresh_BindFragmentSamplers(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
Refresh_TextureSamplerBinding *pBindings
) {
NULL_RETURN(device);
device->BindFragmentSamplers(
device->driverData,
commandBuffer,
pTextures,
pSamplers
pBindings
);
}
@ -662,26 +654,26 @@ void Refresh_BindComputePipeline(
void Refresh_BindComputeBuffers(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer **pBuffers
Refresh_ComputeBufferBinding *pBindings
) {
NULL_RETURN(device);
device->BindComputeBuffers(
device->driverData,
commandBuffer,
pBuffers
pBindings
);
}
void Refresh_BindComputeTextures(
Refresh_Device *device,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice **pTextureSlices
Refresh_ComputeTextureBinding *pBindings
) {
NULL_RETURN(device);
device->BindComputeTextures(
device->driverData,
commandBuffer,
pTextureSlices
pBindings
);
}
@ -735,7 +727,7 @@ void Refresh_SetTransferData(
void* data,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
) {
NULL_RETURN(device);
device->SetTransferData(
@ -743,7 +735,7 @@ void Refresh_SetTransferData(
data,
transferBuffer,
copyParams,
option
transferOption
);
}
@ -781,7 +773,7 @@ void Refresh_UploadToTexture(
Refresh_TransferBuffer *transferBuffer,
Refresh_TextureRegion *textureRegion,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
NULL_RETURN(device);
device->UploadToTexture(
@ -790,7 +782,7 @@ void Refresh_UploadToTexture(
transferBuffer,
textureRegion,
copyParams,
option
writeOption
);
}
@ -800,7 +792,7 @@ void Refresh_UploadToBuffer(
Refresh_TransferBuffer *transferBuffer,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
NULL_RETURN(device);
device->UploadToBuffer(
@ -809,7 +801,7 @@ void Refresh_UploadToBuffer(
transferBuffer,
gpuBuffer,
copyParams,
option
writeOption
);
}
@ -819,7 +811,7 @@ void Refresh_DownloadFromTexture(
Refresh_TextureRegion *textureRegion,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferImageCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
) {
NULL_RETURN(device);
device->DownloadFromTexture(
@ -828,7 +820,7 @@ void Refresh_DownloadFromTexture(
textureRegion,
transferBuffer,
copyParams,
option
transferOption
);
}
@ -838,7 +830,7 @@ void Refresh_DownloadFromBuffer(
Refresh_GpuBuffer *gpuBuffer,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
) {
NULL_RETURN(device);
device->DownloadFromBuffer(
@ -847,7 +839,7 @@ void Refresh_DownloadFromBuffer(
gpuBuffer,
transferBuffer,
copyParams,
option
transferOption
);
}
@ -856,7 +848,7 @@ void Refresh_CopyTextureToTexture(
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureRegion *source,
Refresh_TextureRegion *destination,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
NULL_RETURN(device);
device->CopyTextureToTexture(
@ -864,7 +856,7 @@ void Refresh_CopyTextureToTexture(
commandBuffer,
source,
destination,
option
writeOption
);
}
@ -874,7 +866,7 @@ void Refresh_CopyTextureToBuffer(
Refresh_TextureRegion *textureRegion,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferImageCopy *copyParameters,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
NULL_RETURN(device);
device->CopyTextureToBuffer(
@ -883,7 +875,7 @@ void Refresh_CopyTextureToBuffer(
textureRegion,
gpuBuffer,
copyParameters,
option
writeOption
);
}
@ -893,7 +885,7 @@ void Refresh_CopyBufferToTexture(
Refresh_GpuBuffer *gpuBuffer,
Refresh_TextureRegion *textureRegion,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
NULL_RETURN(device);
device->CopyBufferToTexture(
@ -902,7 +894,7 @@ void Refresh_CopyBufferToTexture(
gpuBuffer,
textureRegion,
copyParams,
option
writeOption
);
}
@ -912,7 +904,7 @@ void Refresh_CopyBufferToBuffer(
Refresh_GpuBuffer *source,
Refresh_GpuBuffer *destination,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
NULL_RETURN(device);
device->CopyBufferToBuffer(
@ -921,7 +913,7 @@ void Refresh_CopyBufferToBuffer(
source,
destination,
copyParams,
option
writeOption
);
}

View File

@ -289,30 +289,26 @@ struct Refresh_Device
Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
Refresh_GpuBuffer **pBuffers,
uint64_t *pOffsets
Refresh_BufferBinding *pBindings
);
void (*BindIndexBuffer)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer *gpuBuffer,
uint64_t offset,
Refresh_BufferBinding *pBinding,
Refresh_IndexElementSize indexElementSize
);
void (*BindVertexSamplers)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
Refresh_TextureSamplerBinding *pBindings
);
void (*BindFragmentSamplers)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
Refresh_TextureSamplerBinding *pBindings
);
void (*PushVertexShaderUniforms)(
@ -383,13 +379,13 @@ struct Refresh_Device
void (*BindComputeBuffers)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer **pBuffers
Refresh_ComputeBufferBinding *pBindings
);
void (*BindComputeTextures)(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice **pTextureSlices
Refresh_ComputeTextureBinding *pBindings
);
void (*PushComputeShaderUniforms)(
@ -419,7 +415,7 @@ struct Refresh_Device
void* data,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
);
void (*GetTransferData)(
@ -442,7 +438,7 @@ struct Refresh_Device
Refresh_TransferBuffer *transferBuffer,
Refresh_TextureRegion *textureSlice,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
void (*UploadToBuffer)(
@ -451,7 +447,7 @@ struct Refresh_Device
Refresh_TransferBuffer *transferBuffer,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
void (*DownloadFromTexture)(
@ -460,7 +456,7 @@ struct Refresh_Device
Refresh_TextureRegion *textureSlice,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferImageCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
);
void (*DownloadFromBuffer)(
@ -469,7 +465,7 @@ struct Refresh_Device
Refresh_GpuBuffer *gpuBuffer,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
);
void (*CopyTextureToTexture)(
@ -477,7 +473,7 @@ struct Refresh_Device
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureRegion *source,
Refresh_TextureRegion *destination,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
void (*CopyTextureToBuffer)(
@ -486,7 +482,7 @@ struct Refresh_Device
Refresh_TextureRegion *textureSlice,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
void (*CopyBufferToTexture)(
@ -495,7 +491,7 @@ struct Refresh_Device
Refresh_GpuBuffer *gpuBuffer,
Refresh_TextureRegion *textureSlice,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
void (*CopyBufferToBuffer)(
@ -504,7 +500,7 @@ struct Refresh_Device
Refresh_GpuBuffer *source,
Refresh_GpuBuffer *destination,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
);
void (*GenerateMipmaps)(

View File

@ -5712,6 +5712,49 @@ static VulkanTextureHandle* VULKAN_INTERNAL_CreateTextureHandle(
return textureHandle;
}
static void VULKAN_INTERNAL_DiscardActiveBuffer(
VulkanRenderer *renderer,
VulkanBufferContainer *bufferContainer
) {
VulkanBufferHandle *bufferHandle;
uint32_t i;
/* If a previously-discarded buffer is available, we can use that. */
for (i = 0; i < bufferContainer->bufferCount; i += 1)
{
bufferHandle = bufferContainer->bufferHandles[i];
if (SDL_AtomicGet(&bufferHandle->vulkanBuffer->referenceCount) == 0)
{
bufferContainer->activeBufferHandle = bufferHandle;
return;
}
}
/* No buffer handle is available, generate a new one. */
bufferContainer->activeBufferHandle = VULKAN_INTERNAL_CreateBufferHandle(
renderer,
bufferContainer->activeBufferHandle->vulkanBuffer->size,
RESOURCE_ACCESS_NONE,
bufferContainer->activeBufferHandle->vulkanBuffer->usage,
bufferContainer->activeBufferHandle->vulkanBuffer->requireHostVisible,
bufferContainer->activeBufferHandle->vulkanBuffer->preferHostLocal,
bufferContainer->activeBufferHandle->vulkanBuffer->preferDeviceLocal
);
EXPAND_ARRAY_IF_NEEDED(
bufferContainer->bufferHandles,
VulkanBufferHandle*,
bufferContainer->bufferCount + 1,
bufferContainer->bufferCapacity,
bufferContainer->bufferCapacity * 2
);
bufferContainer->bufferHandles[
bufferContainer->bufferCount
] = bufferContainer->activeBufferHandle;
bufferContainer->bufferCount += 1;
}
static void VULKAN_INTERNAL_DiscardActiveTexture(
VulkanRenderer *renderer,
VulkanTextureContainer *textureContainer
@ -7172,98 +7215,6 @@ static VkDescriptorSet VULKAN_INTERNAL_FetchDescriptorSet(
return descriptorSet;
}
static void VULKAN_BindVertexSamplers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanGraphicsPipeline *graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline;
VulkanTexture *currentTexture;
VulkanSampler *currentSampler;
uint32_t i, samplerCount, sliceIndex;
VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS];
if (graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL)
{
return;
}
samplerCount = graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache->bindingCount;
for (i = 0; i < samplerCount; i += 1)
{
currentTexture = ((VulkanTextureContainer*) pTextures[i])->activeTextureHandle->vulkanTexture;
currentSampler = (VulkanSampler*) pSamplers[i];
descriptorImageInfos[i].imageView = currentTexture->view;
descriptorImageInfos[i].sampler = currentSampler->sampler;
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VULKAN_INTERNAL_TrackSampler(renderer, vulkanCommandBuffer, currentSampler);
for (sliceIndex = 0; sliceIndex < currentTexture->sliceCount; sliceIndex += 1)
{
VULKAN_INTERNAL_TrackTextureSlice(renderer, vulkanCommandBuffer, &currentTexture->slices[sliceIndex]);
}
}
vulkanCommandBuffer->vertexSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
renderer,
vulkanCommandBuffer,
graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache,
descriptorImageInfos,
NULL
);
}
static void VULKAN_BindFragmentSamplers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_Texture **pTextures,
Refresh_Sampler **pSamplers
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanGraphicsPipeline *graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline;
VulkanTexture *currentTexture;
VulkanSampler *currentSampler;
uint32_t i, samplerCount, sliceIndex;
VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS];
if (graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL)
{
return;
}
samplerCount = graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache->bindingCount;
for (i = 0; i < samplerCount; i += 1)
{
currentTexture = ((VulkanTextureContainer*) pTextures[i])->activeTextureHandle->vulkanTexture;
currentSampler = (VulkanSampler*) pSamplers[i];
descriptorImageInfos[i].imageView = currentTexture->view;
descriptorImageInfos[i].sampler = currentSampler->sampler;
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VULKAN_INTERNAL_TrackSampler(renderer, vulkanCommandBuffer, currentSampler);
for (sliceIndex = 0; sliceIndex < currentTexture->sliceCount; sliceIndex += 1)
{
VULKAN_INTERNAL_TrackTextureSlice(renderer, vulkanCommandBuffer, &currentTexture->slices[sliceIndex]);
}
}
vulkanCommandBuffer->fragmentSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
renderer,
vulkanCommandBuffer,
graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache,
descriptorImageInfos,
NULL
);
}
static void VULKAN_INTERNAL_QueueDestroyTexture(
VulkanRenderer *renderer,
VulkanTexture *vulkanTexture
@ -7793,7 +7744,7 @@ static void VULKAN_BeginRenderPass(
textureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&colorAttachmentInfos[i].textureSlice);
if (
colorAttachmentInfos[i].safeDiscard &&
colorAttachmentInfos[i].writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
colorAttachmentInfos[i].loadOp != REFRESH_LOADOP_LOAD &&
textureContainer->canBeDiscarded &&
SDL_AtomicGet(&textureSlice->referenceCount) > 0
@ -7805,7 +7756,6 @@ static void VULKAN_BeginRenderPass(
textureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&colorAttachmentInfos[i].textureSlice);
}
w = textureSlice->parent->dimensions.width >> colorAttachmentInfos[i].textureSlice.mipLevel;
h = textureSlice->parent->dimensions.height >> colorAttachmentInfos[i].textureSlice.mipLevel;
@ -7834,7 +7784,7 @@ static void VULKAN_BeginRenderPass(
textureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&depthStencilAttachmentInfo->textureSlice);
if (
depthStencilAttachmentInfo->safeDiscard &&
depthStencilAttachmentInfo->writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
depthStencilAttachmentInfo->loadOp != REFRESH_LOADOP_LOAD &&
depthStencilAttachmentInfo->stencilLoadOp != REFRESH_LOADOP_LOAD &&
textureContainer->canBeDiscarded &&
@ -8031,6 +7981,197 @@ static void VULKAN_BeginRenderPass(
);
}
static void VULKAN_BindGraphicsPipeline(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_GraphicsPipeline *graphicsPipeline
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline;
/* bind dummy sets if necessary */
if (pipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL)
{
vulkanCommandBuffer->vertexSamplerDescriptorSet = renderer->emptyVertexSamplerDescriptorSet;
}
if (pipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL)
{
vulkanCommandBuffer->fragmentSamplerDescriptorSet = renderer->emptyFragmentSamplerDescriptorSet;
}
renderer->vkCmdBindPipeline(
vulkanCommandBuffer->commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline->pipeline
);
vulkanCommandBuffer->currentGraphicsPipeline = pipeline;
VULKAN_INTERNAL_TrackGraphicsPipeline(renderer, vulkanCommandBuffer, pipeline);
renderer->vkCmdSetViewport(
vulkanCommandBuffer->commandBuffer,
0,
1,
&vulkanCommandBuffer->currentViewport
);
renderer->vkCmdSetScissor(
vulkanCommandBuffer->commandBuffer,
0,
1,
&vulkanCommandBuffer->currentScissor
);
}
static void VULKAN_BindVertexBuffers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
Refresh_BufferBinding *pBindings
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanBuffer *currentVulkanBuffer;
VkBuffer *buffers = SDL_stack_alloc(VkBuffer, bindingCount);
VkDeviceSize *offsets = SDL_stack_alloc(VkDeviceSize, bindingCount);
uint32_t i;
for (i = 0; i < bindingCount; i += 1)
{
currentVulkanBuffer = ((VulkanBufferContainer*) pBindings[i].gpuBuffer)->activeBufferHandle->vulkanBuffer;
buffers[i] = currentVulkanBuffer->buffer;
offsets[i] = (VkDeviceSize) pBindings[i].offset;
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, currentVulkanBuffer);
}
renderer->vkCmdBindVertexBuffers(
vulkanCommandBuffer->commandBuffer,
firstBinding,
bindingCount,
buffers,
offsets
);
SDL_stack_free(buffers);
SDL_stack_free(offsets);
}
static void VULKAN_BindIndexBuffer(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_BufferBinding *pBinding,
Refresh_IndexElementSize indexElementSize
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) pBinding->gpuBuffer)->activeBufferHandle->vulkanBuffer;
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer);
renderer->vkCmdBindIndexBuffer(
vulkanCommandBuffer->commandBuffer,
vulkanBuffer->buffer,
(VkDeviceSize) pBinding->offset,
RefreshToVK_IndexType[indexElementSize]
);
}
static void VULKAN_BindVertexSamplers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSamplerBinding *pBindings
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanGraphicsPipeline *graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline;
VulkanTexture *currentTexture;
VulkanSampler *currentSampler;
uint32_t i, samplerCount, sliceIndex;
VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS];
if (graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL)
{
return;
}
samplerCount = graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache->bindingCount;
for (i = 0; i < samplerCount; i += 1)
{
currentTexture = ((VulkanTextureContainer*) pBindings[i].texture)->activeTextureHandle->vulkanTexture;
currentSampler = (VulkanSampler*) pBindings[i].sampler;
descriptorImageInfos[i].imageView = currentTexture->view;
descriptorImageInfos[i].sampler = currentSampler->sampler;
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VULKAN_INTERNAL_TrackSampler(renderer, vulkanCommandBuffer, currentSampler);
for (sliceIndex = 0; sliceIndex < currentTexture->sliceCount; sliceIndex += 1)
{
VULKAN_INTERNAL_TrackTextureSlice(renderer, vulkanCommandBuffer, &currentTexture->slices[sliceIndex]);
}
}
vulkanCommandBuffer->vertexSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
renderer,
vulkanCommandBuffer,
graphicsPipeline->pipelineLayout->vertexSamplerDescriptorSetCache,
descriptorImageInfos,
NULL
);
}
static void VULKAN_BindFragmentSamplers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSamplerBinding *pBindings
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanGraphicsPipeline *graphicsPipeline = vulkanCommandBuffer->currentGraphicsPipeline;
VulkanTexture *currentTexture;
VulkanSampler *currentSampler;
uint32_t i, samplerCount, sliceIndex;
VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS];
if (graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL)
{
return;
}
samplerCount = graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache->bindingCount;
for (i = 0; i < samplerCount; i += 1)
{
currentTexture = ((VulkanTextureContainer*) pBindings[i].texture)->activeTextureHandle->vulkanTexture;
currentSampler = (VulkanSampler*) pBindings[i].sampler;
descriptorImageInfos[i].imageView = currentTexture->view;
descriptorImageInfos[i].sampler = currentSampler->sampler;
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VULKAN_INTERNAL_TrackSampler(renderer, vulkanCommandBuffer, currentSampler);
for (sliceIndex = 0; sliceIndex < currentTexture->sliceCount; sliceIndex += 1)
{
VULKAN_INTERNAL_TrackTextureSlice(renderer, vulkanCommandBuffer, &currentTexture->slices[sliceIndex]);
}
}
vulkanCommandBuffer->fragmentSamplerDescriptorSet = VULKAN_INTERNAL_FetchDescriptorSet(
renderer,
vulkanCommandBuffer,
graphicsPipeline->pipelineLayout->fragmentSamplerDescriptorSetCache,
descriptorImageInfos,
NULL
);
}
static void VULKAN_EndRenderPass(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer
@ -8089,104 +8230,6 @@ static void VULKAN_EndRenderPass(
vulkanCommandBuffer->currentGraphicsPipeline = NULL;
}
static void VULKAN_BindGraphicsPipeline(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_GraphicsPipeline *graphicsPipeline
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline;
/* bind dummy sets if necessary */
if (pipeline->pipelineLayout->vertexSamplerDescriptorSetCache == NULL)
{
vulkanCommandBuffer->vertexSamplerDescriptorSet = renderer->emptyVertexSamplerDescriptorSet;
}
if (pipeline->pipelineLayout->fragmentSamplerDescriptorSetCache == NULL)
{
vulkanCommandBuffer->fragmentSamplerDescriptorSet = renderer->emptyFragmentSamplerDescriptorSet;
}
renderer->vkCmdBindPipeline(
vulkanCommandBuffer->commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline->pipeline
);
vulkanCommandBuffer->currentGraphicsPipeline = pipeline;
VULKAN_INTERNAL_TrackGraphicsPipeline(renderer, vulkanCommandBuffer, pipeline);
renderer->vkCmdSetViewport(
vulkanCommandBuffer->commandBuffer,
0,
1,
&vulkanCommandBuffer->currentViewport
);
renderer->vkCmdSetScissor(
vulkanCommandBuffer->commandBuffer,
0,
1,
&vulkanCommandBuffer->currentScissor
);
}
static void VULKAN_BindVertexBuffers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
Refresh_GpuBuffer **pBuffers,
uint64_t *pOffsets
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanBuffer *currentVulkanBuffer;
VkBuffer *buffers = SDL_stack_alloc(VkBuffer, bindingCount);
uint32_t i;
for (i = 0; i < bindingCount; i += 1)
{
currentVulkanBuffer = ((VulkanBufferContainer*) pBuffers[i])->activeBufferHandle->vulkanBuffer;
buffers[i] = currentVulkanBuffer->buffer;
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, currentVulkanBuffer);
}
renderer->vkCmdBindVertexBuffers(
vulkanCommandBuffer->commandBuffer,
firstBinding,
bindingCount,
buffers,
pOffsets
);
SDL_stack_free(buffers);
}
static void VULKAN_BindIndexBuffer(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer *gpuBuffer,
uint64_t offset,
Refresh_IndexElementSize indexElementSize
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanBuffer* vulkanBuffer = ((VulkanBufferContainer*) gpuBuffer)->activeBufferHandle->vulkanBuffer;
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer);
renderer->vkCmdBindIndexBuffer(
vulkanCommandBuffer->commandBuffer,
vulkanBuffer->buffer,
offset,
RefreshToVK_IndexType[indexElementSize]
);
}
static void VULKAN_BeginComputePass(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer
@ -8231,12 +8274,13 @@ static void VULKAN_BindComputePipeline(
static void VULKAN_BindComputeBuffers(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_GpuBuffer **pBuffers
Refresh_ComputeBufferBinding *pBindings
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline;
VulkanBufferContainer *bufferContainer;
VulkanBuffer *currentVulkanBuffer;
VkDescriptorBufferInfo descriptorBufferInfos[MAX_BUFFER_BINDINGS];
uint32_t i;
@ -8248,11 +8292,19 @@ static void VULKAN_BindComputeBuffers(
for (i = 0; i < computePipeline->pipelineLayout->bufferDescriptorSetCache->bindingCount; i += 1)
{
currentVulkanBuffer = ((VulkanBufferContainer*) pBuffers[i])->activeBufferHandle->vulkanBuffer;
bufferContainer = (VulkanBufferContainer*) pBindings[i].gpuBuffer;
currentVulkanBuffer = bufferContainer->activeBufferHandle->vulkanBuffer;
descriptorBufferInfos[i].buffer = currentVulkanBuffer->buffer;
descriptorBufferInfos[i].offset = 0;
descriptorBufferInfos[i].range = currentVulkanBuffer->size;
if (
pBindings[i].writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&bufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
renderer,
bufferContainer
);
currentVulkanBuffer = bufferContainer->activeBufferHandle->vulkanBuffer;
}
VULKAN_INTERNAL_BufferMemoryBarrier(
renderer,
@ -8261,6 +8313,10 @@ static void VULKAN_BindComputeBuffers(
currentVulkanBuffer
);
descriptorBufferInfos[i].buffer = currentVulkanBuffer->buffer;
descriptorBufferInfos[i].offset = 0;
descriptorBufferInfos[i].range = currentVulkanBuffer->size;
VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, currentVulkanBuffer);
VULKAN_INTERNAL_TrackComputeBuffer(renderer, vulkanCommandBuffer, currentVulkanBuffer);
}
@ -8278,12 +8334,12 @@ static void VULKAN_BindComputeBuffers(
static void VULKAN_BindComputeTextures(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureSlice **pTextureSlices
Refresh_ComputeTextureBinding *pBindings
) {
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline;
VulkanTextureContainer *currentTextureContainer;
VulkanTextureSlice *currentTextureSlice;
VkDescriptorImageInfo descriptorImageInfos[MAX_TEXTURE_SAMPLERS];
uint32_t i;
@ -8295,10 +8351,19 @@ static void VULKAN_BindComputeTextures(
for (i = 0; i < computePipeline->pipelineLayout->imageDescriptorSetCache->bindingCount; i += 1)
{
currentTextureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(pTextureSlices[i]);
descriptorImageInfos[i].imageView = currentTextureSlice->view;
descriptorImageInfos[i].sampler = VK_NULL_HANDLE;
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
currentTextureContainer = (VulkanTextureContainer*) pBindings[i].textureSlice.texture;
currentTextureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&pBindings[i].textureSlice);
if (
pBindings[i].writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&currentTextureSlice->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveTexture(
renderer,
currentTextureContainer
);
currentTextureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&pBindings[i].textureSlice);
}
VULKAN_INTERNAL_ImageMemoryBarrier(
renderer,
@ -8307,6 +8372,10 @@ static void VULKAN_BindComputeTextures(
currentTextureSlice
);
descriptorImageInfos[i].imageView = currentTextureSlice->view;
descriptorImageInfos[i].sampler = VK_NULL_HANDLE;
descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
VULKAN_INTERNAL_TrackTextureSlice(renderer, vulkanCommandBuffer, currentTextureSlice);
VULKAN_INTERNAL_TrackComputeTextureSlice(renderer, vulkanCommandBuffer, currentTextureSlice);
}
@ -8415,61 +8484,18 @@ static void VULKAN_EndComputePass(
vulkanCommandBuffer->currentComputePipeline = NULL;
}
static void VULKAN_INTERNAL_DiscardActiveBuffer(
VulkanRenderer *renderer,
VulkanBufferContainer *bufferContainer
) {
VulkanBufferHandle *bufferHandle;
uint32_t i;
/* If a previously-discarded buffer is available, we can use that. */
for (i = 0; i < bufferContainer->bufferCount; i += 1)
{
bufferHandle = bufferContainer->bufferHandles[i];
if (SDL_AtomicGet(&bufferHandle->vulkanBuffer->referenceCount) == 0)
{
bufferContainer->activeBufferHandle = bufferHandle;
return;
}
}
/* No buffer handle is available, generate a new one. */
bufferContainer->activeBufferHandle = VULKAN_INTERNAL_CreateBufferHandle(
renderer,
bufferContainer->activeBufferHandle->vulkanBuffer->size,
RESOURCE_ACCESS_NONE,
bufferContainer->activeBufferHandle->vulkanBuffer->usage,
bufferContainer->activeBufferHandle->vulkanBuffer->requireHostVisible,
bufferContainer->activeBufferHandle->vulkanBuffer->preferHostLocal,
bufferContainer->activeBufferHandle->vulkanBuffer->preferDeviceLocal
);
EXPAND_ARRAY_IF_NEEDED(
bufferContainer->bufferHandles,
VulkanBufferHandle*,
bufferContainer->bufferCount + 1,
bufferContainer->bufferCapacity,
bufferContainer->bufferCapacity * 2
);
bufferContainer->bufferHandles[
bufferContainer->bufferCount
] = bufferContainer->activeBufferHandle;
bufferContainer->bufferCount += 1;
}
static void VULKAN_SetTransferData(
Refresh_Renderer *driverData,
void* data,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanBufferContainer *transferBufferContainer = (VulkanBufferContainer*) transferBuffer;
if (
option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
transferOption == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
@ -8529,7 +8555,7 @@ static void VULKAN_UploadToTexture(
Refresh_TransferBuffer *transferBuffer,
Refresh_TextureRegion *textureRegion,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8541,7 +8567,7 @@ static void VULKAN_UploadToTexture(
vulkanTextureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&textureRegion->textureSlice);
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
vulkanTextureContainer->canBeDiscarded &&
SDL_AtomicGet(&vulkanTextureSlice->referenceCount) > 0
) {
@ -8601,7 +8627,7 @@ static void VULKAN_UploadToBuffer(
Refresh_TransferBuffer *transferBuffer,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8610,7 +8636,7 @@ static void VULKAN_UploadToBuffer(
VkBufferCopy bufferCopy;
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&gpuBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
@ -8656,7 +8682,7 @@ static void VULKAN_DownloadFromTexture(
Refresh_TextureRegion *textureRegion,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferImageCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8667,7 +8693,7 @@ static void VULKAN_DownloadFromTexture(
vulkanTextureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&textureRegion->textureSlice);
if (
option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
transferOption == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
@ -8725,7 +8751,7 @@ static void VULKAN_DownloadFromBuffer(
Refresh_GpuBuffer *gpuBuffer,
Refresh_TransferBuffer *transferBuffer,
Refresh_BufferCopy *copyParams,
Refresh_TransferOptions option
Refresh_TransferOptions transferOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8734,7 +8760,7 @@ static void VULKAN_DownloadFromBuffer(
VkBufferCopy bufferCopy;
if (
option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
transferOption == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
@ -8779,7 +8805,7 @@ static void VULKAN_CopyTextureToTexture(
Refresh_CommandBuffer *commandBuffer,
Refresh_TextureRegion *source,
Refresh_TextureRegion *destination,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8792,7 +8818,7 @@ static void VULKAN_CopyTextureToTexture(
dstSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&destination->textureSlice);
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
dstContainer->canBeDiscarded &&
SDL_AtomicGet(&dstSlice->referenceCount) > 0
) {
@ -8857,7 +8883,7 @@ static void VULKAN_CopyTextureToBuffer(
Refresh_TextureRegion *textureRegion,
Refresh_GpuBuffer *gpuBuffer,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8868,7 +8894,7 @@ static void VULKAN_CopyTextureToBuffer(
vulkanTextureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&textureRegion->textureSlice);
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&bufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
@ -8926,7 +8952,7 @@ static void VULKAN_CopyBufferToTexture(
Refresh_GpuBuffer *gpuBuffer,
Refresh_TextureRegion *textureRegion,
Refresh_BufferImageCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -8938,7 +8964,7 @@ static void VULKAN_CopyBufferToTexture(
vulkanTextureSlice = VULKAN_INTERNAL_RefreshToVulkanTextureSlice(&textureRegion->textureSlice);
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
textureContainer->canBeDiscarded &&
SDL_AtomicGet(&vulkanTextureSlice->referenceCount) > 0
) {
@ -8998,7 +9024,7 @@ static void VULKAN_CopyBufferToBuffer(
Refresh_GpuBuffer *source,
Refresh_GpuBuffer *destination,
Refresh_BufferCopy *copyParams,
Refresh_CopyOptions option
Refresh_WriteOptions writeOption
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
@ -9007,7 +9033,7 @@ static void VULKAN_CopyBufferToBuffer(
VkBufferCopy bufferCopy;
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&dstContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(