mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 19:24:11 +01:00
[dxvk] Initialize dummy resources to zero
Read access to unbound images and buffers usually yields a result vector that contains zeroes in all components.
This commit is contained in:
parent
d4a0581f8f
commit
c66492a90f
@ -196,7 +196,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (m_vki->vkCreateDevice(m_handle, &info, nullptr, &device) != VK_SUCCESS)
|
if (m_vki->vkCreateDevice(m_handle, &info, nullptr, &device) != VK_SUCCESS)
|
||||||
throw DxvkError("DxvkAdapter: Failed to create device");
|
throw DxvkError("DxvkAdapter: Failed to create device");
|
||||||
return new DxvkDevice(this, new vk::DeviceFn(m_vki->instance(), device), extensions, enabledFeatures);
|
|
||||||
|
Rc<DxvkDevice> result = new DxvkDevice(this,
|
||||||
|
new vk::DeviceFn(m_vki->instance(), device),
|
||||||
|
extensions, enabledFeatures);
|
||||||
|
result->initResources();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,6 +304,17 @@ namespace dxvk {
|
|||||||
m_vkd->vkCmdEndRenderPass(m_buffer);
|
m_vkd->vkCmdEndRenderPass(m_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmdFillBuffer(
|
||||||
|
VkBuffer dstBuffer,
|
||||||
|
VkDeviceSize dstOffset,
|
||||||
|
VkDeviceSize size,
|
||||||
|
uint32_t data) {
|
||||||
|
m_vkd->vkCmdFillBuffer(m_buffer,
|
||||||
|
dstBuffer, dstOffset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmdPipelineBarrier(
|
void cmdPipelineBarrier(
|
||||||
VkPipelineStageFlags srcStageMask,
|
VkPipelineStageFlags srcStageMask,
|
||||||
VkPipelineStageFlags dstStageMask,
|
VkPipelineStageFlags dstStageMask,
|
||||||
|
@ -175,6 +175,32 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::clearBuffer(
|
||||||
|
const Rc<DxvkBuffer>& buffer,
|
||||||
|
VkDeviceSize offset,
|
||||||
|
VkDeviceSize length,
|
||||||
|
uint32_t value) {
|
||||||
|
this->renderPassEnd();
|
||||||
|
|
||||||
|
auto slice = buffer->subSlice(offset, length);
|
||||||
|
|
||||||
|
m_cmd->cmdFillBuffer(
|
||||||
|
slice.handle(),
|
||||||
|
slice.offset(),
|
||||||
|
slice.length(),
|
||||||
|
value);
|
||||||
|
|
||||||
|
m_barriers.accessBuffer(slice,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
buffer->info().stages,
|
||||||
|
buffer->info().access);
|
||||||
|
m_barriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
|
m_cmd->trackResource(slice.resource());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::clearColorImage(
|
void DxvkContext::clearColorImage(
|
||||||
const Rc<DxvkImage>& image,
|
const Rc<DxvkImage>& image,
|
||||||
const VkClearColorValue& value,
|
const VkClearColorValue& value,
|
||||||
|
@ -135,6 +135,23 @@ namespace dxvk {
|
|||||||
const DxvkBufferSlice& buffer,
|
const DxvkBufferSlice& buffer,
|
||||||
uint32_t stride);
|
uint32_t stride);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clears a buffer with a fixed value
|
||||||
|
*
|
||||||
|
* Note that both \c offset and \c length must
|
||||||
|
* be multiples of four, and that \c value is
|
||||||
|
* consumed as a four-byte word.
|
||||||
|
* \param [in] buffer The buffer to clear
|
||||||
|
* \param [in] offset Offset of the range to clear
|
||||||
|
* \param [in] length Bumber of bytes to clear
|
||||||
|
* \param [in] value Clear value
|
||||||
|
*/
|
||||||
|
void clearBuffer(
|
||||||
|
const Rc<DxvkBuffer>& buffer,
|
||||||
|
VkDeviceSize offset,
|
||||||
|
VkDeviceSize length,
|
||||||
|
uint32_t value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Clears subresources of a color image
|
* \brief Clears subresources of a color image
|
||||||
*
|
*
|
||||||
|
@ -192,6 +192,11 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkDevice::initResources() {
|
||||||
|
m_unboundResources.clearResources(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VkResult DxvkDevice::presentSwapImage(
|
VkResult DxvkDevice::presentSwapImage(
|
||||||
const VkPresentInfoKHR& presentInfo) {
|
const VkPresentInfoKHR& presentInfo) {
|
||||||
m_statCounters.increment(DxvkStat::DevQueuePresents, 1);
|
m_statCounters.increment(DxvkStat::DevQueuePresents, 1);
|
||||||
|
@ -35,6 +35,7 @@ namespace dxvk {
|
|||||||
* contexts. Multiple contexts can be created for a device.
|
* contexts. Multiple contexts can be created for a device.
|
||||||
*/
|
*/
|
||||||
class DxvkDevice : public RcObject {
|
class DxvkDevice : public RcObject {
|
||||||
|
friend class DxvkContext;
|
||||||
friend class DxvkSubmissionQueue;
|
friend class DxvkSubmissionQueue;
|
||||||
|
|
||||||
constexpr static VkDeviceSize DefaultStagingBufferSize = 4 * 1024 * 1024;
|
constexpr static VkDeviceSize DefaultStagingBufferSize = 4 * 1024 * 1024;
|
||||||
@ -276,46 +277,13 @@ namespace dxvk {
|
|||||||
const DxvkSwapchainProperties& properties);
|
const DxvkSwapchainProperties& properties);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Dummy buffer handle
|
* \brief Initializes dummy resources
|
||||||
* \returns Use for unbound vertex buffers.
|
|
||||||
*/
|
|
||||||
VkBuffer dummyBufferHandle() const {
|
|
||||||
return m_unboundResources.bufferHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Dummy buffer descriptor
|
|
||||||
* \returns Descriptor that points to a dummy buffer
|
|
||||||
*/
|
|
||||||
VkDescriptorBufferInfo dummyBufferDescriptor() const {
|
|
||||||
return m_unboundResources.bufferDescriptor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Dummy buffer view descriptor
|
|
||||||
* \returns Dummy buffer view handle
|
|
||||||
*/
|
|
||||||
VkBufferView dummyBufferViewDescriptor() const {
|
|
||||||
return m_unboundResources.bufferViewDescriptor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Dummy sampler descriptor
|
|
||||||
* \returns Descriptor that points to a dummy sampler
|
|
||||||
*/
|
|
||||||
VkDescriptorImageInfo dummySamplerDescriptor() const {
|
|
||||||
return m_unboundResources.samplerDescriptor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Dummy image view descriptor
|
|
||||||
*
|
*
|
||||||
* \param [in] type Required view type
|
* Should be called after creating the device in
|
||||||
* \returns Descriptor that points to a dummy image
|
* case the device initialization was successful
|
||||||
|
* and the device is usable.
|
||||||
*/
|
*/
|
||||||
VkDescriptorImageInfo dummyImageViewDescriptor(VkImageViewType type) const {
|
void initResources();
|
||||||
return m_unboundResources.imageViewDescriptor(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Presents a swap chain image
|
* \brief Presents a swap chain image
|
||||||
@ -379,7 +347,6 @@ namespace dxvk {
|
|||||||
VkQueue m_graphicsQueue = VK_NULL_HANDLE;
|
VkQueue m_graphicsQueue = VK_NULL_HANDLE;
|
||||||
VkQueue m_presentQueue = VK_NULL_HANDLE;
|
VkQueue m_presentQueue = VK_NULL_HANDLE;
|
||||||
|
|
||||||
// TODO fine-tune buffer sizes
|
|
||||||
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
|
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
|
||||||
DxvkRecycler<DxvkStagingBuffer, 4> m_recycledStagingBuffers;
|
DxvkRecycler<DxvkStagingBuffer, 4> m_recycledStagingBuffers;
|
||||||
|
|
||||||
@ -390,6 +357,48 @@ namespace dxvk {
|
|||||||
void recycleCommandList(
|
void recycleCommandList(
|
||||||
const Rc<DxvkCommandList>& cmdList);
|
const Rc<DxvkCommandList>& cmdList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Dummy buffer handle
|
||||||
|
* \returns Use for unbound vertex buffers.
|
||||||
|
*/
|
||||||
|
VkBuffer dummyBufferHandle() const {
|
||||||
|
return m_unboundResources.bufferHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Dummy buffer descriptor
|
||||||
|
* \returns Descriptor that points to a dummy buffer
|
||||||
|
*/
|
||||||
|
VkDescriptorBufferInfo dummyBufferDescriptor() const {
|
||||||
|
return m_unboundResources.bufferDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Dummy buffer view descriptor
|
||||||
|
* \returns Dummy buffer view handle
|
||||||
|
*/
|
||||||
|
VkBufferView dummyBufferViewDescriptor() const {
|
||||||
|
return m_unboundResources.bufferViewDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Dummy sampler descriptor
|
||||||
|
* \returns Descriptor that points to a dummy sampler
|
||||||
|
*/
|
||||||
|
VkDescriptorImageInfo dummySamplerDescriptor() const {
|
||||||
|
return m_unboundResources.samplerDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Dummy image view descriptor
|
||||||
|
*
|
||||||
|
* \param [in] type Required view type
|
||||||
|
* \returns Descriptor that points to a dummy image
|
||||||
|
*/
|
||||||
|
VkDescriptorImageInfo dummyImageViewDescriptor(VkImageViewType type) const {
|
||||||
|
return m_unboundResources.imageViewDescriptor(type);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -25,6 +25,21 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkUnboundResources::clearResources(DxvkDevice* dev) {
|
||||||
|
const Rc<DxvkContext> ctx = dev->createContext();
|
||||||
|
ctx->beginRecording(dev->createCommandList());
|
||||||
|
|
||||||
|
this->clearBuffer(ctx, m_buffer);
|
||||||
|
this->clearImage(ctx, m_image1D);
|
||||||
|
this->clearImage(ctx, m_image2D);
|
||||||
|
this->clearImage(ctx, m_image3D);
|
||||||
|
|
||||||
|
dev->submitCommandList(
|
||||||
|
ctx->endRecording(),
|
||||||
|
nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkSampler> DxvkUnboundResources::createSampler(DxvkDevice* dev) {
|
Rc<DxvkSampler> DxvkUnboundResources::createSampler(DxvkDevice* dev) {
|
||||||
DxvkSamplerCreateInfo info;
|
DxvkSamplerCreateInfo info;
|
||||||
info.minFilter = VK_FILTER_LINEAR;
|
info.minFilter = VK_FILTER_LINEAR;
|
||||||
@ -50,11 +65,13 @@ namespace dxvk {
|
|||||||
Rc<DxvkBuffer> DxvkUnboundResources::createBuffer(DxvkDevice* dev) {
|
Rc<DxvkBuffer> DxvkUnboundResources::createBuffer(DxvkDevice* dev) {
|
||||||
DxvkBufferCreateInfo info;
|
DxvkBufferCreateInfo info;
|
||||||
info.size = 4;
|
info.size = 4;
|
||||||
info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||||
|
| VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||||
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
|
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
|
||||||
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
||||||
info.stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||||
|
| VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||||
| VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
|
| VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
|
||||||
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
|
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
|
||||||
| VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
|
| VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
|
||||||
@ -93,9 +110,11 @@ namespace dxvk {
|
|||||||
info.extent = { 1, 1, 1 };
|
info.extent = { 1, 1, 1 };
|
||||||
info.numLayers = layers;
|
info.numLayers = layers;
|
||||||
info.mipLevels = 1;
|
info.mipLevels = 1;
|
||||||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT
|
info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||||
|
| VK_IMAGE_USAGE_SAMPLED_BIT
|
||||||
| VK_IMAGE_USAGE_STORAGE_BIT;
|
| VK_IMAGE_USAGE_STORAGE_BIT;
|
||||||
info.stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||||
|
| VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||||
| VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
|
| VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
|
||||||
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
|
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
|
||||||
| VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
|
| VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
|
||||||
@ -147,4 +166,23 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkUnboundResources::clearBuffer(
|
||||||
|
const Rc<DxvkContext>& ctx,
|
||||||
|
const Rc<DxvkBuffer>& buffer) {
|
||||||
|
ctx->clearBuffer(buffer, 0, buffer->info().size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkUnboundResources::clearImage(
|
||||||
|
const Rc<DxvkContext>& ctx,
|
||||||
|
const Rc<DxvkImage>& image) {
|
||||||
|
ctx->clearColorImage(image,
|
||||||
|
VkClearColorValue { },
|
||||||
|
VkImageSubresourceRange {
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
0, image->info().mipLevels,
|
||||||
|
0, image->info().numLayers });
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -35,8 +35,9 @@ namespace dxvk {
|
|||||||
/**
|
/**
|
||||||
* \brief Dummy buffer descriptor
|
* \brief Dummy buffer descriptor
|
||||||
*
|
*
|
||||||
* Points to a small buffer with undefined
|
* Points to a small buffer filled with zeroes.
|
||||||
* values. Do not access this buffer.
|
* Do not write to this buffer, and do not use
|
||||||
|
* it if out-of-bounds read access is possible.
|
||||||
* \returns Dummy buffer descriptor
|
* \returns Dummy buffer descriptor
|
||||||
*/
|
*/
|
||||||
VkDescriptorBufferInfo bufferDescriptor() const {
|
VkDescriptorBufferInfo bufferDescriptor() const {
|
||||||
@ -95,6 +96,14 @@ namespace dxvk {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clears the resources
|
||||||
|
*
|
||||||
|
* Initializes all images and buffers to zero.
|
||||||
|
* \param [in] dev The DXVK device handle
|
||||||
|
*/
|
||||||
|
void clearResources(DxvkDevice* dev);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<DxvkSampler> m_sampler;
|
Rc<DxvkSampler> m_sampler;
|
||||||
@ -136,6 +145,14 @@ namespace dxvk {
|
|||||||
const DxvkImageView* getImageView(
|
const DxvkImageView* getImageView(
|
||||||
VkImageViewType type) const;
|
VkImageViewType type) const;
|
||||||
|
|
||||||
|
void clearBuffer(
|
||||||
|
const Rc<DxvkContext>& ctx,
|
||||||
|
const Rc<DxvkBuffer>& buffer);
|
||||||
|
|
||||||
|
void clearImage(
|
||||||
|
const Rc<DxvkContext>& ctx,
|
||||||
|
const Rc<DxvkImage>& image);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user