Vulkan: added support for wrapping existing textures
This commit is contained in:
parent
2adbcce864
commit
0454e1fdb4
2 changed files with 41 additions and 48 deletions
|
@ -616,6 +616,10 @@ extern DECLSPEC SDL_Texture *SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer *
|
||||||
* associated with the V plane of a YUV texture, if you want to wrap an
|
* associated with the V plane of a YUV texture, if you want to wrap an
|
||||||
* existing texture.
|
* existing texture.
|
||||||
*
|
*
|
||||||
|
* With the vulkan renderer:
|
||||||
|
*
|
||||||
|
* - `SDL_PROP_TEXTURE_CREATE_VULKAN_TEXTURE_NUMBER`: the VkImage with layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL associated with the texture, if you want to wrap an existing texture.
|
||||||
|
*
|
||||||
* \param renderer the rendering context
|
* \param renderer the rendering context
|
||||||
* \param props the properties to use
|
* \param props the properties to use
|
||||||
* \returns a pointer to the created texture or NULL if no rendering context
|
* \returns a pointer to the created texture or NULL if no rendering context
|
||||||
|
@ -655,6 +659,7 @@ extern DECLSPEC SDL_Texture *SDLCALL SDL_CreateTextureWithProperties(SDL_Rendere
|
||||||
#define SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_UV_NUMBER "opengles2.texture_uv"
|
#define SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_UV_NUMBER "opengles2.texture_uv"
|
||||||
#define SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_U_NUMBER "opengles2.texture_u"
|
#define SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_U_NUMBER "opengles2.texture_u"
|
||||||
#define SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_V_NUMBER "opengles2.texture_v"
|
#define SDL_PROP_TEXTURE_CREATE_OPENGLES2_TEXTURE_V_NUMBER "opengles2.texture_v"
|
||||||
|
#define SDL_PROP_TEXTURE_CREATE_VULKAN_TEXTURE_NUMBER "vulkan.texture"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the properties associated with a texture.
|
* Get the properties associated with a texture.
|
||||||
|
@ -734,6 +739,10 @@ extern DECLSPEC SDL_Texture *SDLCALL SDL_CreateTextureWithProperties(SDL_Rendere
|
||||||
* - `SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER`: the GLenum for the
|
* - `SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER`: the GLenum for the
|
||||||
* texture target (`GL_TEXTURE_2D`, `GL_TEXTURE_EXTERNAL_OES`, etc)
|
* texture target (`GL_TEXTURE_2D`, `GL_TEXTURE_EXTERNAL_OES`, etc)
|
||||||
*
|
*
|
||||||
|
* With the vulkan renderer:
|
||||||
|
*
|
||||||
|
* - `SDL_PROP_TEXTURE_VULKAN_TEXTURE_NUMBER`: the VkImage associated with the texture
|
||||||
|
*
|
||||||
* \param texture the texture to query
|
* \param texture the texture to query
|
||||||
* \returns a valid property ID on success or 0 on failure; call
|
* \returns a valid property ID on success or 0 on failure; call
|
||||||
* SDL_GetError() for more information.
|
* SDL_GetError() for more information.
|
||||||
|
@ -766,10 +775,7 @@ extern DECLSPEC SDL_PropertiesID SDLCALL SDL_GetTextureProperties(SDL_Texture *t
|
||||||
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_U_NUMBER "SDL.texture.opengles2.texture_u"
|
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_U_NUMBER "SDL.texture.opengles2.texture_u"
|
||||||
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_V_NUMBER "SDL.texture.opengles2.texture_v"
|
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_V_NUMBER "SDL.texture.opengles2.texture_v"
|
||||||
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER "SDL.texture.opengles2.target"
|
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER "SDL.texture.opengles2.target"
|
||||||
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_POINTER "SDL.texture.vulkan.texture"
|
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_NUMBER "SDL.texture.vulkan.texture"
|
||||||
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_U_POINTER "SDL.texture.vulkan.texture_u"
|
|
||||||
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_V_POINTER "SDL.texture.vulkan.texture_v"
|
|
||||||
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_UV_POINTER "SDL.texture.vulkan.texture_uv"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the renderer that created an SDL_Texture.
|
* Get the renderer that created an SDL_Texture.
|
||||||
|
|
|
@ -689,25 +689,27 @@ static void VULKAN_DestroyImage(VULKAN_RenderData *rendererData, VULKAN_Image *v
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vulkanImage->deviceMemory != VK_NULL_HANDLE) {
|
if (vulkanImage->deviceMemory != VK_NULL_HANDLE) {
|
||||||
|
if (vulkanImage->allocatedImage) {
|
||||||
vkFreeMemory(rendererData->device, vulkanImage->deviceMemory, NULL);
|
vkFreeMemory(rendererData->device, vulkanImage->deviceMemory, NULL);
|
||||||
|
}
|
||||||
vulkanImage->deviceMemory = VK_NULL_HANDLE;
|
vulkanImage->deviceMemory = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
SDL_memset(vulkanImage, 0, sizeof(VULKAN_Image));
|
SDL_memset(vulkanImage, 0, sizeof(VULKAN_Image));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, uint32_t width, uint32_t height, VkFormat format,
|
static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, SDL_PropertiesID create_props, uint32_t width, uint32_t height, VkFormat format, VkImageUsageFlags imageUsage, VkComponentMapping swizzle, VkSamplerYcbcrConversionKHR samplerYcbcrConversion, VULKAN_Image *imageOut)
|
||||||
VkImageUsageFlags imageUsage, VkComponentMapping swizzle, VkImage externalImage,
|
|
||||||
VkSamplerYcbcrConversionKHR samplerYcbcrConversion,
|
|
||||||
VULKAN_Image *imageOut)
|
|
||||||
{
|
{
|
||||||
VkResult result;
|
VkResult result;
|
||||||
VkImageCreateInfo imageCreateInfo = { 0 };
|
|
||||||
VkSamplerYcbcrConversionInfoKHR samplerYcbcrConversionInfo = { 0 };
|
VkSamplerYcbcrConversionInfoKHR samplerYcbcrConversionInfo = { 0 };
|
||||||
|
|
||||||
SDL_memset(imageOut, 0, sizeof(VULKAN_Image));
|
SDL_memset(imageOut, 0, sizeof(VULKAN_Image));
|
||||||
imageOut->format = format;
|
imageOut->format = format;
|
||||||
imageOut->imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
imageOut->image = (VkImage)SDL_GetNumberProperty(create_props, SDL_PROP_TEXTURE_CREATE_VULKAN_TEXTURE_NUMBER, 0);
|
||||||
|
|
||||||
|
if (imageOut->image == VK_NULL_HANDLE) {
|
||||||
|
imageOut->allocatedImage = VK_TRUE;
|
||||||
|
|
||||||
|
VkImageCreateInfo imageCreateInfo = { 0 };
|
||||||
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
imageCreateInfo.flags = 0;
|
imageCreateInfo.flags = 0;
|
||||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
@ -724,9 +726,6 @@ static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, uint32_t w
|
||||||
imageCreateInfo.queueFamilyIndexCount = 0;
|
imageCreateInfo.queueFamilyIndexCount = 0;
|
||||||
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
imageOut->allocatedImage = VK_FALSE;
|
|
||||||
if (externalImage == VK_NULL_HANDLE) {
|
|
||||||
imageOut->allocatedImage = VK_TRUE;
|
|
||||||
result = vkCreateImage(rendererData->device, &imageCreateInfo, NULL, &imageOut->image);
|
result = vkCreateImage(rendererData->device, &imageCreateInfo, NULL, &imageOut->image);
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
VULKAN_DestroyImage(rendererData, imageOut);
|
VULKAN_DestroyImage(rendererData, imageOut);
|
||||||
|
@ -765,13 +764,15 @@ static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, uint32_t w
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkBindImageMemory(): %s\n", SDL_Vulkan_GetResultString(result));
|
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkBindImageMemory(): %s\n", SDL_Vulkan_GetResultString(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
imageOut->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageViewCreateInfo imageViewCreateInfo = { 0 };
|
VkImageViewCreateInfo imageViewCreateInfo = { 0 };
|
||||||
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
imageViewCreateInfo.image = imageOut->image;
|
imageViewCreateInfo.image = imageOut->image;
|
||||||
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
imageViewCreateInfo.format = imageCreateInfo.format;
|
imageViewCreateInfo.format = format;
|
||||||
imageViewCreateInfo.components = swizzle;
|
imageViewCreateInfo.components = swizzle;
|
||||||
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
|
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
@ -779,7 +780,7 @@ static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, uint32_t w
|
||||||
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
|
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
imageViewCreateInfo.subresourceRange.layerCount = 1;
|
imageViewCreateInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
/* If it's a YcBcBr image, we need to pass the conversion info to the VkImageView (and the VkSampler) */
|
/* If it's a YCbCr image, we need to pass the conversion info to the VkImageView (and the VkSampler) */
|
||||||
if (samplerYcbcrConversion != VK_NULL_HANDLE) {
|
if (samplerYcbcrConversion != VK_NULL_HANDLE) {
|
||||||
samplerYcbcrConversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR;
|
samplerYcbcrConversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR;
|
||||||
samplerYcbcrConversionInfo.conversion = samplerYcbcrConversion;
|
samplerYcbcrConversionInfo.conversion = samplerYcbcrConversion;
|
||||||
|
@ -2395,22 +2396,11 @@ static SDL_bool VULKAN_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode b
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetTextureProperty(SDL_PropertiesID props, const char *name, VkImage *image)
|
|
||||||
{
|
|
||||||
VkImage *propImage = (VkImage*)SDL_GetProperty(props, name, NULL);
|
|
||||||
if (propImage) {
|
|
||||||
*image = *propImage;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int VULKAN_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
|
static int VULKAN_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
|
||||||
{
|
{
|
||||||
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->driverdata;
|
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->driverdata;
|
||||||
VULKAN_TextureData *textureData;
|
VULKAN_TextureData *textureData;
|
||||||
VkResult result;
|
VkResult result;
|
||||||
VkImage externalImage = VK_NULL_HANDLE;
|
|
||||||
VkFormat textureFormat = SDLPixelFormatToVkTextureFormat(texture->format, renderer->output_colorspace);
|
VkFormat textureFormat = SDLPixelFormatToVkTextureFormat(texture->format, renderer->output_colorspace);
|
||||||
uint32_t width = texture->w;
|
uint32_t width = texture->w;
|
||||||
uint32_t height = texture->h;
|
uint32_t height = texture->h;
|
||||||
|
@ -2562,17 +2552,14 @@ static int VULKAN_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||||
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetTextureProperty(create_props, "vulkan.texture", &externalImage) < 0) {
|
result = VULKAN_AllocateImage(rendererData, create_props, width, height, textureFormat, usage, imageViewSwizzle, textureData->samplerYcbcrConversion, &textureData->mainImage);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = VULKAN_AllocateImage(rendererData, width, height, textureFormat, usage, imageViewSwizzle, externalImage, textureData->samplerYcbcrConversion, &textureData->mainImage);
|
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_AllocateImage(): %s\n", SDL_Vulkan_GetResultString(result));
|
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_AllocateImage(): %s\n", SDL_Vulkan_GetResultString(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_VULKAN_TEXTURE_POINTER, &textureData->mainImage.image);
|
SDL_PropertiesID props = SDL_GetTextureProperties(texture);
|
||||||
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_VULKAN_TEXTURE_NUMBER, (Sint64)textureData->mainImage.image);
|
||||||
|
|
||||||
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
|
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
|
||||||
result = VULKAN_CreateFramebuffersAndRenderPasses(renderer,
|
result = VULKAN_CreateFramebuffersAndRenderPasses(renderer,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue