mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
vulkan: fix missing resource validation in Shader:send
This commit is contained in:
@@ -655,7 +655,6 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe
|
|||||||
|
|
||||||
count = std::min(count, info->count);
|
count = std::min(count, info->count);
|
||||||
|
|
||||||
// Bind the textures to the texture units.
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
love::graphics::Buffer *buffer = buffers[i];
|
love::graphics::Buffer *buffer = buffers[i];
|
||||||
|
|||||||
@@ -362,39 +362,80 @@ void Shader::updateUniform(const UniformInfo *info, int count)
|
|||||||
|
|
||||||
void Shader::sendTextures(const UniformInfo *info, graphics::Texture **textures, int count)
|
void Shader::sendTextures(const UniformInfo *info, graphics::Texture **textures, int count)
|
||||||
{
|
{
|
||||||
|
bool issampler = info->baseType == UNIFORM_SAMPLER;
|
||||||
|
bool isstoragetex = info->baseType == UNIFORM_STORAGETEXTURE;
|
||||||
|
|
||||||
|
count = std::min(count, info->count);
|
||||||
|
|
||||||
if (current == this)
|
if (current == this)
|
||||||
Graphics::flushBatchedDrawsGlobal();
|
Graphics::flushBatchedDrawsGlobal();
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
love::graphics::Texture *tex = textures[i];
|
||||||
|
bool isdefault = tex == nullptr;
|
||||||
|
|
||||||
|
if (tex != nullptr)
|
||||||
|
{
|
||||||
|
if (!validateTexture(info, tex, false))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
|
||||||
|
tex = gfx->getDefaultTexture(info->textureType, info->dataBaseType, info->isDepthSampler);
|
||||||
|
}
|
||||||
|
|
||||||
int resourceindex = info->resourceIndex + i;
|
int resourceindex = info->resourceIndex + i;
|
||||||
auto prevtexture = activeTextures[resourceindex];
|
auto prevtexture = activeTextures[resourceindex];
|
||||||
activeTextures[resourceindex] = textures[i];
|
activeTextures[resourceindex] = tex;
|
||||||
activeTextures[resourceindex]->retain();
|
activeTextures[resourceindex]->retain();
|
||||||
if (prevtexture)
|
if (prevtexture)
|
||||||
prevtexture->release();
|
prevtexture->release();
|
||||||
|
|
||||||
if (textures[i] != prevtexture)
|
if (tex != prevtexture)
|
||||||
setTextureDescriptor(info, textures[i], i);
|
setTextureDescriptor(info, (isdefault && (info->access & ACCESS_WRITE) != 0) ? nullptr : tex, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count)
|
void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffers, int count)
|
||||||
{
|
{
|
||||||
|
bool texelbinding = info->baseType == UNIFORM_TEXELBUFFER;
|
||||||
|
bool storagebinding = info->baseType == UNIFORM_STORAGEBUFFER;
|
||||||
|
|
||||||
|
count = std::min(count, info->count);
|
||||||
|
|
||||||
if (current == this)
|
if (current == this)
|
||||||
Graphics::flushBatchedDrawsGlobal();
|
Graphics::flushBatchedDrawsGlobal();
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
love::graphics::Buffer *buffer = buffers[i];
|
||||||
|
bool isdefault = buffer == nullptr;
|
||||||
|
|
||||||
|
if (buffer != nullptr)
|
||||||
|
{
|
||||||
|
if (!validateBuffer(info, buffer, false))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
|
||||||
|
if (texelbinding)
|
||||||
|
buffer = gfx->getDefaultTexelBuffer(info->dataBaseType);
|
||||||
|
else
|
||||||
|
buffer = gfx->getDefaultStorageBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
int resourceindex = info->resourceIndex + i;
|
int resourceindex = info->resourceIndex + i;
|
||||||
auto prevbuffer = activeBuffers[resourceindex];
|
auto prevbuffer = activeBuffers[resourceindex];
|
||||||
activeBuffers[resourceindex] = buffers[i];
|
activeBuffers[resourceindex] = buffer;
|
||||||
activeBuffers[resourceindex]->retain();
|
activeBuffers[resourceindex]->retain();
|
||||||
if (prevbuffer)
|
if (prevbuffer)
|
||||||
prevbuffer->release();
|
prevbuffer->release();
|
||||||
|
|
||||||
if (buffers[i] != prevbuffer)
|
if (buffer != prevbuffer)
|
||||||
setBufferDescriptor(info, buffers[i], i);
|
setBufferDescriptor(info, (isdefault && (info->access & ACCESS_WRITE) != 0) ? nullptr : buffer, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,7 +1111,8 @@ void Shader::setMainTex(graphics::Texture *texture)
|
|||||||
if (u != nullptr)
|
if (u != nullptr)
|
||||||
{
|
{
|
||||||
auto prevtexture = activeTextures[u->resourceIndex];
|
auto prevtexture = activeTextures[u->resourceIndex];
|
||||||
texture->retain();
|
if (texture != nullptr)
|
||||||
|
texture->retain();
|
||||||
if (prevtexture)
|
if (prevtexture)
|
||||||
prevtexture->release();
|
prevtexture->release();
|
||||||
activeTextures[u->resourceIndex] = texture;
|
activeTextures[u->resourceIndex] = texture;
|
||||||
@@ -1088,8 +1130,8 @@ void Shader::setTextureDescriptor(const UniformInfo *info, love::graphics::Textu
|
|||||||
|
|
||||||
// Samplers may change after this call, so they're set just before the
|
// Samplers may change after this call, so they're set just before the
|
||||||
// descriptor set is used instead of here.
|
// descriptor set is used instead of here.
|
||||||
imageInfo.imageLayout = vkTexture->getImageLayout();
|
imageInfo.imageLayout = vkTexture != nullptr ? vkTexture->getImageLayout() : VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
imageInfo.imageView = (VkImageView)vkTexture->getRenderTargetHandle();
|
imageInfo.imageView = vkTexture != nullptr ? (VkImageView)vkTexture->getRenderTargetHandle() : VK_NULL_HANDLE;
|
||||||
|
|
||||||
resourceDescriptorsDirty = true;
|
resourceDescriptorsDirty = true;
|
||||||
}
|
}
|
||||||
@@ -1099,13 +1141,13 @@ void Shader::setBufferDescriptor(const UniformInfo *info, love::graphics::Buffer
|
|||||||
if (info->baseType == UNIFORM_STORAGEBUFFER)
|
if (info->baseType == UNIFORM_STORAGEBUFFER)
|
||||||
{
|
{
|
||||||
VkDescriptorBufferInfo &bufferInfo = descriptorBuffers[info->bindingStartIndex + index];
|
VkDescriptorBufferInfo &bufferInfo = descriptorBuffers[info->bindingStartIndex + index];
|
||||||
bufferInfo.buffer = (VkBuffer)buffer->getHandle();
|
bufferInfo.buffer = buffer != nullptr ? (VkBuffer)buffer->getHandle() : VK_NULL_HANDLE;
|
||||||
bufferInfo.offset = 0;
|
bufferInfo.offset = 0;
|
||||||
bufferInfo.range = buffer->getSize();
|
bufferInfo.range = buffer != nullptr ? buffer->getSize() : 0;
|
||||||
}
|
}
|
||||||
else if (info->baseType == UNIFORM_TEXELBUFFER)
|
else if (info->baseType == UNIFORM_TEXELBUFFER)
|
||||||
{
|
{
|
||||||
descriptorBufferViews[info->bindingStartIndex + index] = (VkBufferView)buffer->getTexelBufferHandle();
|
descriptorBufferViews[info->bindingStartIndex + index] = buffer != nullptr ? (VkBufferView)buffer->getTexelBufferHandle() : VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceDescriptorsDirty = true;
|
resourceDescriptorsDirty = true;
|
||||||
|
|||||||
@@ -772,7 +772,7 @@ VkDescriptorType Vulkan::getDescriptorType(graphics::Shader::UniformType type)
|
|||||||
case graphics::Shader::UniformType::UNIFORM_INT:
|
case graphics::Shader::UniformType::UNIFORM_INT:
|
||||||
case graphics::Shader::UniformType::UNIFORM_UINT:
|
case graphics::Shader::UniformType::UNIFORM_UINT:
|
||||||
case graphics::Shader::UniformType::UNIFORM_BOOL:
|
case graphics::Shader::UniformType::UNIFORM_BOOL:
|
||||||
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
||||||
case graphics::Shader::UniformType::UNIFORM_SAMPLER:
|
case graphics::Shader::UniformType::UNIFORM_SAMPLER:
|
||||||
return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
case graphics::Shader::UniformType::UNIFORM_STORAGETEXTURE:
|
case graphics::Shader::UniformType::UNIFORM_STORAGETEXTURE:
|
||||||
|
|||||||
Reference in New Issue
Block a user