mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxvk] Optimized resource binding
Fixes a few bottlenecks that were encountered in the Cascading Shadow Maps demo from the Microsoft SDK. Performance is now slightly better than wined3d with CSMT, MESA_NO_ERROR and mesa_glthread enabled.
This commit is contained in:
parent
f68655feff
commit
2ed2d892d6
@ -11,11 +11,13 @@ namespace dxvk {
|
||||
// 14 - 29: Samplers
|
||||
// 30 - 157: Shader resources
|
||||
// 158 - 221: Uniform access views
|
||||
const uint32_t stageOffset = 12 + 158 * 5;
|
||||
|
||||
switch (bindingType) {
|
||||
case DxbcBindingType::ConstantBuffer: return bindingIndex + 0;
|
||||
case DxbcBindingType::ImageSampler: return bindingIndex + 14;
|
||||
case DxbcBindingType::ShaderResource: return bindingIndex + 30;
|
||||
case DxbcBindingType::UnorderedAccessView:return bindingIndex + 158;
|
||||
case DxbcBindingType::ConstantBuffer: return bindingIndex + stageOffset + 0;
|
||||
case DxbcBindingType::ImageSampler: return bindingIndex + stageOffset + 14;
|
||||
case DxbcBindingType::ShaderResource: return bindingIndex + stageOffset + 30;
|
||||
case DxbcBindingType::UnorderedAccessView:return bindingIndex + stageOffset + 158;
|
||||
default: Logger::err("computeResourceSlotId: Invalid resource type");
|
||||
}
|
||||
} else {
|
||||
|
@ -17,33 +17,4 @@ namespace dxvk {
|
||||
DxvkBufferSlice bufferSlice;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Shader resource slots
|
||||
*/
|
||||
class DxvkShaderResourceSlots {
|
||||
|
||||
public:
|
||||
|
||||
DxvkShaderResourceSlots() { }
|
||||
DxvkShaderResourceSlots(size_t n) {
|
||||
m_resources.resize(n);
|
||||
}
|
||||
|
||||
const DxvkShaderResourceSlot& getShaderResource(uint32_t slot) const {
|
||||
return m_resources.at(slot);
|
||||
}
|
||||
|
||||
void bindShaderResource(
|
||||
uint32_t slot,
|
||||
const DxvkShaderResourceSlot& resource) {
|
||||
m_resources.at(slot) = resource;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<DxvkShaderResourceSlot> m_resources;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -254,6 +254,10 @@ namespace dxvk {
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
Rc<DxvkResource> resource() const {
|
||||
return m_buffer->resource();
|
||||
}
|
||||
|
||||
VkBuffer handle() const {
|
||||
return m_buffer != nullptr
|
||||
? m_buffer->handle()
|
||||
|
@ -108,7 +108,7 @@ namespace dxvk {
|
||||
std::array<VkWriteDescriptorSet, MaxNumResourceSlots> descriptorWrites;
|
||||
|
||||
for (uint32_t i = 0; i < descriptorCount; i++) {
|
||||
auto& curr = descriptorWrites.at(i);
|
||||
auto& curr = descriptorWrites[i];
|
||||
auto& binding = descriptorSlots[i];
|
||||
|
||||
curr.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
|
@ -73,15 +73,9 @@ namespace dxvk {
|
||||
VkPipelineBindPoint pipe,
|
||||
uint32_t slot,
|
||||
const DxvkBufferSlice& buffer) {
|
||||
auto rc = this->getShaderResourceSlots(pipe);
|
||||
|
||||
if (rc->getShaderResource(slot).bufferSlice != buffer) {
|
||||
if (m_rc[slot].bufferSlice != buffer) {
|
||||
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.bufferSlice = buffer;
|
||||
|
||||
rc->bindShaderResource(slot, resource);
|
||||
m_rc[slot].bufferSlice = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,15 +84,9 @@ namespace dxvk {
|
||||
VkPipelineBindPoint pipe,
|
||||
uint32_t slot,
|
||||
const Rc<DxvkBufferView>& bufferView) {
|
||||
auto rc = this->getShaderResourceSlots(pipe);
|
||||
|
||||
if (rc->getShaderResource(slot).bufferView != bufferView) {
|
||||
if (m_rc[slot].bufferView != bufferView) {
|
||||
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.bufferView = bufferView;
|
||||
|
||||
rc->bindShaderResource(slot, resource);
|
||||
m_rc[slot].bufferView = bufferView;
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,15 +95,9 @@ namespace dxvk {
|
||||
VkPipelineBindPoint pipe,
|
||||
uint32_t slot,
|
||||
const Rc<DxvkImageView>& image) {
|
||||
auto rc = this->getShaderResourceSlots(pipe);
|
||||
|
||||
if (rc->getShaderResource(slot).imageView != image) {
|
||||
if (m_rc[slot].imageView != image) {
|
||||
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.imageView = image;
|
||||
|
||||
rc->bindShaderResource(slot, resource);
|
||||
m_rc[slot].imageView = image;
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,15 +106,9 @@ namespace dxvk {
|
||||
VkPipelineBindPoint pipe,
|
||||
uint32_t slot,
|
||||
const Rc<DxvkSampler>& sampler) {
|
||||
auto rc = this->getShaderResourceSlots(pipe);
|
||||
|
||||
if (rc->getShaderResource(slot).sampler != sampler) {
|
||||
if (m_rc[slot].sampler != sampler) {
|
||||
m_flags.set(this->getResourceDirtyFlag(pipe));
|
||||
|
||||
DxvkShaderResourceSlot resource;
|
||||
resource.sampler = sampler;
|
||||
|
||||
rc->bindShaderResource(slot, resource);
|
||||
m_rc[slot].sampler = sampler;
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,13 +148,13 @@ namespace dxvk {
|
||||
uint32_t binding,
|
||||
const DxvkBufferSlice& buffer,
|
||||
uint32_t stride) {
|
||||
if (m_state.vi.vertexBuffers.at(binding) != buffer) {
|
||||
m_state.vi.vertexBuffers.at(binding) = buffer;
|
||||
if (m_state.vi.vertexBuffers[binding] != buffer) {
|
||||
m_state.vi.vertexBuffers[binding] = buffer;
|
||||
m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers);
|
||||
}
|
||||
|
||||
if (m_state.vi.vertexStrides.at(binding) != stride) {
|
||||
m_state.vi.vertexStrides.at(binding) = stride;
|
||||
if (m_state.vi.vertexStrides[binding] != stride) {
|
||||
m_state.vi.vertexStrides[binding] = stride;
|
||||
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
}
|
||||
@ -606,8 +582,8 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < viewportCount; i++) {
|
||||
m_state.vp.viewports.at(i) = viewports[i];
|
||||
m_state.vp.scissorRects.at(i) = scissorRects[i];
|
||||
m_state.vp.viewports[i] = viewports[i];
|
||||
m_state.vp.scissorRects[i] = scissorRects[i];
|
||||
}
|
||||
|
||||
this->updateViewports();
|
||||
@ -649,10 +625,10 @@ namespace dxvk {
|
||||
m_state.il.numBindings = bindingCount;
|
||||
|
||||
for (uint32_t i = 0; i < attributeCount; i++)
|
||||
m_state.il.attributes.at(i) = attributes[i];
|
||||
m_state.il.attributes[i] = attributes[i];
|
||||
|
||||
for (uint32_t i = 0; i < bindingCount; i++)
|
||||
m_state.il.bindings.at(i) = bindings[i];
|
||||
m_state.il.bindings[i] = bindings[i];
|
||||
}
|
||||
|
||||
|
||||
@ -687,7 +663,7 @@ namespace dxvk {
|
||||
void DxvkContext::setBlendMode(
|
||||
uint32_t attachment,
|
||||
const DxvkBlendMode& blendMode) {
|
||||
m_state.om.blendModes.at(attachment) = blendMode;
|
||||
m_state.om.blendModes[attachment] = blendMode;
|
||||
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
|
||||
}
|
||||
|
||||
@ -779,7 +755,7 @@ namespace dxvk {
|
||||
for (uint32_t i = 0; i < m_state.il.numBindings; i++) {
|
||||
gpState.ilBindings[i].binding = m_state.il.bindings[i].binding;
|
||||
gpState.ilBindings[i].inputRate = m_state.il.bindings[i].inputRate;
|
||||
gpState.ilBindings[i].stride = m_state.vi.vertexStrides.at(i);
|
||||
gpState.ilBindings[i].stride = m_state.vi.vertexStrides[i];
|
||||
}
|
||||
|
||||
gpState.rsEnableDepthClamp = m_state.rs.enableDepthClamp;
|
||||
@ -818,7 +794,7 @@ namespace dxvk {
|
||||
|
||||
for (uint32_t i = 0; i < DxvkLimits::MaxNumRenderTargets; i++) {
|
||||
if (rt.getColorTarget(i) != nullptr) {
|
||||
const DxvkBlendMode& mode = m_state.om.blendModes.at(i);
|
||||
const DxvkBlendMode& mode = m_state.om.blendModes[i];
|
||||
|
||||
gpState.omBlendAttachments[i].blendEnable = mode.enableBlending;
|
||||
gpState.omBlendAttachments[i].srcColorBlendFactor = mode.colorSrcFactor;
|
||||
@ -869,34 +845,30 @@ namespace dxvk {
|
||||
// compute can use this code as well
|
||||
for (uint32_t i = 0; i < layout->bindingCount(); i++) {
|
||||
const uint32_t slot = layout->binding(i).slot;
|
||||
const auto& res = m_gResources.getShaderResource(slot);
|
||||
|
||||
DxvkDescriptorInfo descriptor;
|
||||
const auto& res = m_rc[slot];
|
||||
|
||||
if (res.sampler != nullptr) {
|
||||
m_descriptors[i].image.sampler = res.sampler->handle();
|
||||
m_descriptors[i].image.imageView = VK_NULL_HANDLE;
|
||||
m_descriptors[i].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
m_cmd->trackResource(res.sampler);
|
||||
descriptor.image.sampler = res.sampler->handle();
|
||||
}
|
||||
|
||||
if (res.imageView != nullptr) {
|
||||
} else if (res.imageView != nullptr) {
|
||||
m_descriptors[i].image.sampler = VK_NULL_HANDLE;
|
||||
m_descriptors[i].image.imageView = res.imageView->handle();
|
||||
m_descriptors[i].image.imageLayout = res.imageView->imageInfo().layout;
|
||||
|
||||
m_cmd->trackResource(res.imageView);
|
||||
m_cmd->trackResource(res.imageView->image());
|
||||
descriptor.image.imageView = res.imageView->handle();
|
||||
descriptor.image.imageLayout = res.imageView->imageInfo().layout;
|
||||
}
|
||||
|
||||
if (res.bufferView != nullptr) {
|
||||
} else if (res.bufferView != nullptr) {
|
||||
m_descriptors[i].texelBuffer = res.bufferView->handle();
|
||||
|
||||
m_cmd->trackResource(res.bufferView);
|
||||
m_cmd->trackResource(res.bufferView->buffer()->resource());
|
||||
descriptor.texelBuffer = res.bufferView->handle();
|
||||
} else if (res.bufferSlice.handle() != VK_NULL_HANDLE) {
|
||||
m_descriptors[i].buffer = res.bufferSlice.descriptorInfo();
|
||||
m_cmd->trackResource(res.bufferSlice.resource());
|
||||
}
|
||||
|
||||
if (res.bufferSlice.handle() != VK_NULL_HANDLE) {
|
||||
m_cmd->trackResource(res.bufferSlice.buffer()->resource());
|
||||
descriptor.buffer = res.bufferSlice.descriptorInfo();
|
||||
}
|
||||
|
||||
descriptors.at(i) = descriptor;
|
||||
}
|
||||
|
||||
m_cmd->bindResourceDescriptors(
|
||||
@ -905,7 +877,7 @@ namespace dxvk {
|
||||
layout->descriptorSetLayout(),
|
||||
layout->bindingCount(),
|
||||
layout->bindings(),
|
||||
descriptors.data());
|
||||
m_descriptors.data());
|
||||
}
|
||||
}
|
||||
|
||||
@ -949,7 +921,7 @@ namespace dxvk {
|
||||
m_state.vi.indexBuffer.offset(),
|
||||
m_state.vi.indexType);
|
||||
m_cmd->trackResource(
|
||||
m_state.vi.indexBuffer.buffer()->resource());
|
||||
m_state.vi.indexBuffer.resource());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -959,15 +931,15 @@ namespace dxvk {
|
||||
if (m_flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) {
|
||||
m_flags.clr(DxvkContextFlag::GpDirtyVertexBuffers);
|
||||
|
||||
for (uint32_t i = 0; i < m_state.vi.vertexBuffers.size(); i++) {
|
||||
const DxvkBufferSlice vbo = m_state.vi.vertexBuffers.at(i);
|
||||
for (uint32_t i = 0; i < m_state.il.numBindings; i++) {
|
||||
const DxvkBufferSlice& vbo = m_state.vi.vertexBuffers[i];
|
||||
|
||||
VkBuffer handle = vbo.handle();
|
||||
VkDeviceSize offset = vbo.offset();
|
||||
const VkBuffer handle = vbo.handle();
|
||||
const VkDeviceSize offset = vbo.offset();
|
||||
|
||||
if (handle != VK_NULL_HANDLE) {
|
||||
m_cmd->cmdBindVertexBuffers(i, 1, &handle, &offset);
|
||||
m_cmd->trackResource(vbo.buffer()->resource());
|
||||
m_cmd->trackResource(vbo.resource());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1089,15 +1061,6 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DxvkShaderResourceSlots* DxvkContext::getShaderResourceSlots(VkPipelineBindPoint pipe) {
|
||||
switch (pipe) {
|
||||
case VK_PIPELINE_BIND_POINT_GRAPHICS: return &m_gResources;
|
||||
case VK_PIPELINE_BIND_POINT_COMPUTE : return &m_cResources;
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DxvkContextFlag DxvkContext::getResourceDirtyFlag(VkPipelineBindPoint pipe) const {
|
||||
switch (pipe) {
|
||||
default:
|
||||
|
@ -415,10 +415,8 @@ namespace dxvk {
|
||||
DxvkContextState m_state;
|
||||
DxvkBarrierSet m_barriers;
|
||||
|
||||
DxvkShaderResourceSlots m_cResources = { 256 };
|
||||
DxvkShaderResourceSlots m_gResources = { 1024 };
|
||||
|
||||
std::array<DxvkDescriptorInfo, MaxNumResourceSlots> descriptors;
|
||||
std::array<DxvkShaderResourceSlot, MaxNumResourceSlots> m_rc;
|
||||
std::array<DxvkDescriptorInfo, MaxNumResourceSlots> m_descriptors;
|
||||
|
||||
void renderPassBegin();
|
||||
void renderPassEnd();
|
||||
@ -448,9 +446,6 @@ namespace dxvk {
|
||||
void transformLayoutsRenderPassEnd(
|
||||
const DxvkRenderTargets& renderTargets);
|
||||
|
||||
DxvkShaderResourceSlots* getShaderResourceSlots(
|
||||
VkPipelineBindPoint pipe);
|
||||
|
||||
DxvkContextFlag getResourceDirtyFlag(
|
||||
VkPipelineBindPoint pipe) const;
|
||||
|
||||
|
@ -21,13 +21,13 @@ namespace dxvk {
|
||||
|
||||
|
||||
VkDescriptorSet DxvkDescriptorAlloc::alloc(VkDescriptorSetLayout layout) {
|
||||
VkDescriptorSet set = allocFrom(m_pools.at(m_poolId), layout);
|
||||
VkDescriptorSet set = allocFrom(m_pools[m_poolId], layout);
|
||||
|
||||
if (set == VK_NULL_HANDLE) {
|
||||
if (++m_poolId >= m_pools.size())
|
||||
m_pools.push_back(createDescriptorPool());
|
||||
|
||||
set = allocFrom(m_pools.at(m_poolId), layout);
|
||||
set = allocFrom(m_pools[m_poolId], layout);
|
||||
}
|
||||
|
||||
return set;
|
||||
|
@ -10,10 +10,10 @@ namespace dxvk {
|
||||
* Stores information that is required to
|
||||
* update a single resource descriptor.
|
||||
*/
|
||||
struct DxvkDescriptorInfo {
|
||||
VkDescriptorImageInfo image = { VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED };
|
||||
VkDescriptorBufferInfo buffer = { VK_NULL_HANDLE, 0, 0 };
|
||||
VkBufferView texelBuffer = VK_NULL_HANDLE;
|
||||
union DxvkDescriptorInfo {
|
||||
VkDescriptorImageInfo image;
|
||||
VkDescriptorBufferInfo buffer;
|
||||
VkBufferView texelBuffer;
|
||||
};
|
||||
|
||||
|
||||
|
@ -481,7 +481,7 @@ namespace dxvk {
|
||||
const uint32_t formatId = static_cast<uint32_t>(format);
|
||||
|
||||
if (formatId < g_formatInfos.size())
|
||||
return &g_formatInfos.at(formatId);
|
||||
return &g_formatInfos[formatId];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ namespace dxvk {
|
||||
const bool adequate = (m_memProps.memoryTypes[i].propertyFlags & flags) == flags;
|
||||
|
||||
if (supported && adequate) {
|
||||
DxvkMemory memory = m_heaps.at(i)->alloc(req.size, req.alignment);
|
||||
DxvkMemory memory = m_heaps[i]->alloc(req.size, req.alignment);
|
||||
|
||||
if (memory.memory() != VK_NULL_HANDLE)
|
||||
return memory;
|
||||
|
@ -15,7 +15,7 @@ namespace dxvk {
|
||||
uint32_t bindingId = this->getBindingId(slot);
|
||||
|
||||
if (bindingId != InvalidBinding) {
|
||||
m_descriptorSlots.at(bindingId).stages |= stage;
|
||||
m_descriptorSlots[bindingId].stages |= stage;
|
||||
} else {
|
||||
DxvkDescriptorSlot slotInfo;
|
||||
slotInfo.slot = slot;
|
||||
@ -31,7 +31,7 @@ namespace dxvk {
|
||||
// of bindings used by a shader is usually much smaller than
|
||||
// the number of resource slots available to the system.
|
||||
for (uint32_t i = 0; i < m_descriptorSlots.size(); i++) {
|
||||
if (m_descriptorSlots.at(i).slot == slot)
|
||||
if (m_descriptorSlots[i].slot == slot)
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace dxvk {
|
||||
* \returns Resource binding info
|
||||
*/
|
||||
const DxvkDescriptorSlot& binding(uint32_t id) const {
|
||||
return m_bindingSlots.at(id);
|
||||
return m_bindingSlots[id];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,7 @@ namespace dxvk {
|
||||
|
||||
DxvkRenderPassFormat::DxvkRenderPassFormat() {
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
||||
m_color.at(i) = VK_FORMAT_UNDEFINED;
|
||||
m_color[i] = VK_FORMAT_UNDEFINED;
|
||||
m_depth = VK_FORMAT_UNDEFINED;
|
||||
m_samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
@ -16,7 +16,7 @@ namespace dxvk {
|
||||
std::hash<VkSampleCountFlagBits> shash;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++)
|
||||
result.add(fhash(m_color.at(i)));
|
||||
result.add(fhash(m_color[i]));
|
||||
|
||||
result.add(fhash(m_depth));
|
||||
result.add(shash(m_samples));
|
||||
@ -28,7 +28,7 @@ namespace dxvk {
|
||||
bool equal = m_depth == other.m_depth
|
||||
&& m_samples == other.m_samples;
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets && !equal; i++)
|
||||
equal = m_color.at(i) == other.m_color.at(i);
|
||||
equal = m_color[i] == other.m_color[i];
|
||||
return equal;
|
||||
}
|
||||
|
||||
@ -68,8 +68,8 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||
colorRef.at(i).attachment = VK_ATTACHMENT_UNUSED;
|
||||
colorRef.at(i).layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
colorRef[i].attachment = VK_ATTACHMENT_UNUSED;
|
||||
colorRef[i].layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
if (fmt.getColorFormat(i) != VK_FORMAT_UNDEFINED) {
|
||||
VkAttachmentDescription desc;
|
||||
@ -83,8 +83,8 @@ namespace dxvk {
|
||||
desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
colorRef.at(i).attachment = attachments.size();
|
||||
colorRef.at(i).layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
colorRef[i].attachment = attachments.size();
|
||||
colorRef[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachments.push_back(desc);
|
||||
}
|
||||
|
@ -8,13 +8,13 @@ namespace dxvk {
|
||||
|
||||
DxvkStatCounters::DxvkStatCounters(const DxvkStatCounters& other) {
|
||||
for (size_t i = 0; i < m_counters.size(); i++)
|
||||
m_counters.at(i) = other.m_counters.at(i).load();
|
||||
m_counters[i] = other.m_counters[i].load();
|
||||
}
|
||||
|
||||
|
||||
DxvkStatCounters& DxvkStatCounters::operator = (const DxvkStatCounters& other) {
|
||||
for (size_t i = 0; i < m_counters.size(); i++)
|
||||
m_counters.at(i) = other.m_counters.at(i).load();
|
||||
m_counters[i] = other.m_counters[i].load();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -22,20 +22,20 @@ namespace dxvk {
|
||||
DxvkStatCounters DxvkStatCounters::delta(const DxvkStatCounters& oldState) const {
|
||||
DxvkStatCounters result;
|
||||
for (size_t i = 0; i < m_counters.size(); i++)
|
||||
result.m_counters.at(i) = m_counters.at(i) - oldState.m_counters.at(i);;
|
||||
result.m_counters[i] = m_counters[i] - oldState.m_counters[i];;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DxvkStatCounters::addCounters(const DxvkStatCounters& counters) {
|
||||
for (size_t i = 0; i < m_counters.size(); i++)
|
||||
m_counters.at(i) += counters.m_counters.at(i);
|
||||
m_counters[i] += counters.m_counters[i];
|
||||
}
|
||||
|
||||
|
||||
void DxvkStatCounters::clear() {
|
||||
for (size_t i = 0; i < m_counters.size(); i++)
|
||||
m_counters.at(i) = 0;
|
||||
m_counters[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ namespace dxvk {
|
||||
* \param [in] amount Number to add to the counter
|
||||
*/
|
||||
void increment(DxvkStat counter, uint32_t amount) {
|
||||
m_counters.at(counterId(counter)) += amount;
|
||||
m_counters[counterId(counter)] += amount;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +63,7 @@ namespace dxvk {
|
||||
* \returns Current value of the counter
|
||||
*/
|
||||
uint32_t get(DxvkStat counter) const {
|
||||
return m_counters.at(counterId(counter));
|
||||
return m_counters[counterId(counter)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user