vulkan: fix missing resource validation in Shader:send

This commit is contained in:
Sasha Szpakowski
2024-06-22 16:32:10 -03:00
parent ca9aa81744
commit 46402d4ff7
3 changed files with 55 additions and 14 deletions
-1
View File
@@ -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];
+54 -12
View File
@@ -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;
+1 -1
View File
@@ -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: