Merge pull request #15938 from hrydgard/misc-optimizations

Misc optimizations
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2022-09-01 15:03:48 +02:00
commit b5e5f780f2
33 files changed
+219 -138

No files matched your search

+18 -1
View File
@@ -43,6 +43,20 @@ struct TinySet {
slowLookup_->push_back(t);
return slowLookup_->back();
}
void append(const TinySet<T, MaxFastSize> &other) {
size_t otherSize = other.size();
if (size() + otherSize <= MaxFastSize) {
// Fast case
for (int i = 0; i < otherSize; i++) {
fastLookup_[fastCount + i] = other.fastLookup_[i];
}
fastCount += other.fastCount;
} else {
for (int i = 0; i < otherSize; i++) {
push_back(other[i]);
}
}
}
bool contains(T t) const {
for (int i = 0; i < fastCount; i++) {
if (fastLookup_[i] == t)
@@ -79,7 +93,7 @@ struct TinySet {
return fastCount == 0;
}
size_t size() const {
if (fastCount <= MaxFastSize) {
if (!slowLookup_) {
return fastCount;
} else {
return slowLookup_->size() + MaxFastSize;
@@ -92,6 +106,9 @@ struct TinySet {
return (*slowLookup_)[index - MaxFastSize];
}
}
const T &back() const {
return (*this)[size() - 1];
}
private:
void insertSlow(T t) {
+17 -7
View File
@@ -347,6 +347,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
profile->cpuStartTime = time_now_d();
bool emitLabels = vulkan_->Extensions().EXT_debug_utils;
for (size_t i = 0; i < steps.size(); i++) {
const VKRStep &step = *steps[i];
@@ -685,7 +686,7 @@ void VulkanQueueRunner::ApplyRenderPassMerge(std::vector<VKRStep *> &steps) {
auto mergeRenderSteps = [](VKRStep *dst, VKRStep *src) {
// OK. Now, if it's a render, slurp up all the commands and kill the step.
// Also slurp up any pretransitions.
dst->preTransitions.insert(dst->preTransitions.end(), src->preTransitions.begin(), src->preTransitions.end());
dst->preTransitions.append(src->preTransitions);
dst->commands.insert(dst->commands.end(), src->commands.begin(), src->commands.end());
MergeRenderAreaRectInto(&dst->render.renderArea, src->render.renderArea);
// So we don't consider it for other things, maybe doesn't matter.
@@ -1060,7 +1061,8 @@ void TransitionFromOptimal(VkCommandBuffer cmd, VkImage colorImage, VkImageLayou
}
void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer cmd) {
for (const auto &iter : step.preTransitions) {
for (size_t i = 0; i < step.preTransitions.size(); i++) {
const TransitionRequest &iter = step.preTransitions[i];
if (iter.aspect == VK_IMAGE_ASPECT_COLOR_BIT && iter.fb->color.layout != iter.targetLayout) {
recordBarrier_.TransitionImageAuto(
iter.fb->color.image,
@@ -1151,6 +1153,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
// The stencil ones are very commonly mostly redundant so let's eliminate them where possible.
// Might also want to consider scissor and viewport.
VkPipeline lastPipeline = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
int lastStencilWriteMask = -1;
int lastStencilCompareMask = -1;
int lastStencilReference = -1;
@@ -1166,6 +1170,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
VkPipeline pipeline = c.pipeline.pipeline;
if (pipeline != lastGraphicsPipeline) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
lastGraphicsPipeline = pipeline;
// Reset dynamic state so it gets refreshed with the new pipeline.
lastStencilWriteMask = -1;
@@ -1187,6 +1192,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
if (pipeline->pipeline != lastGraphicsPipeline && pipeline->pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
lastGraphicsPipeline = pipeline->pipeline;
// Reset dynamic state so it gets refreshed with the new pipeline.
lastStencilWriteMask = -1;
@@ -1208,6 +1214,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
if (pipeline->pipeline != lastComputePipeline && pipeline->pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->pipeline);
pipelineLayout = c.pipeline.pipelineLayout;
lastComputePipeline = pipeline->pipeline;
}
break;
@@ -1257,7 +1264,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
}
case VKRRenderCommand::PUSH_CONSTANTS:
vkCmdPushConstants(cmd, c.push.pipelineLayout, c.push.stages, c.push.offset, c.push.size, c.push.data);
vkCmdPushConstants(cmd, pipelineLayout, c.push.stages, c.push.offset, c.push.size, c.push.data);
break;
case VKRRenderCommand::STENCIL:
@@ -1276,14 +1283,17 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
break;
case VKRRenderCommand::DRAW_INDEXED:
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, c.drawIndexed.pipelineLayout, 0, 1, &c.drawIndexed.ds, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, c.drawIndexed.indexType);
vkCmdBindVertexBuffers(cmd, 0, 1, &c.drawIndexed.vbuffer, &c.drawIndexed.voffset);
{
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &c.drawIndexed.ds, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, (VkIndexType)c.drawIndexed.indexType);
VkDeviceSize voffset = c.drawIndexed.voffset;
vkCmdBindVertexBuffers(cmd, 0, 1, &c.drawIndexed.vbuffer, &voffset);
vkCmdDrawIndexed(cmd, c.drawIndexed.count, c.drawIndexed.instances, 0, 0, 0);
break;
}
case VKRRenderCommand::DRAW:
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, c.draw.pipelineLayout, 0, 1, &c.draw.ds, c.draw.numUboOffsets, c.draw.uboOffsets);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &c.draw.ds, c.draw.numUboOffsets, c.draw.uboOffsets);
if (c.draw.vbuffer) {
vkCmdBindVertexBuffers(cmd, 0, 1, &c.draw.vbuffer, &c.draw.voffset);
}
+8 -8
View File
@@ -52,15 +52,17 @@ struct VkRenderData {
union {
struct {
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
} pipeline;
struct {
VKRGraphicsPipeline *pipeline;
VkPipelineLayout pipelineLayout;
} graphics_pipeline;
struct {
VKRComputePipeline *pipeline;
VkPipelineLayout pipelineLayout;
} compute_pipeline;
struct {
VkPipelineLayout pipelineLayout;
VkDescriptorSet ds;
int numUboOffsets;
uint32_t uboOffsets[3];
@@ -70,17 +72,16 @@ struct VkRenderData {
uint32_t offset;
} draw;
struct {
VkPipelineLayout pipelineLayout;
VkDescriptorSet ds;
int numUboOffsets;
uint32_t uboOffsets[3];
VkBuffer vbuffer; // might need to increase at some point
VkDeviceSize voffset;
VkBuffer ibuffer;
VkDeviceSize ioffset;
uint32_t voffset;
uint32_t ioffset;
uint32_t count;
int16_t instances;
VkIndexType indexType;
int16_t indexType;
} drawIndexed;
struct {
uint32_t clearColor;
@@ -103,7 +104,6 @@ struct VkRenderData {
uint32_t color;
} blendColor;
struct {
VkPipelineLayout pipelineLayout;
VkShaderStageFlags stages;
uint8_t offset;
uint8_t size;
@@ -134,8 +134,8 @@ enum class VKRRenderPassStoreAction : uint8_t {
};
struct TransitionRequest {
VkImageAspectFlags aspect; // COLOR or DEPTH
VKRFramebuffer *fb;
VkImageAspectFlags aspect; // COLOR or DEPTH
VkImageLayout targetLayout;
};
@@ -153,7 +153,7 @@ struct VKRStep {
VKRStepType stepType;
std::vector<VkRenderData> commands;
std::vector<TransitionRequest> preTransitions;
TinySet<TransitionRequest, 4> preTransitions;
TinySet<VKRFramebuffer *, 8> dependencies;
const char *tag;
union {
+1 -1
View File
@@ -1189,7 +1189,7 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in
// We're done.
return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.depthSampleView;
} else {
curRenderStep_->preTransitions.push_back({ aspectBit, fb, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL });
curRenderStep_->preTransitions.push_back({ fb, aspectBit, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL });
return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.depthSampleView;
}
}
+8 -8
View File
@@ -242,29 +242,32 @@ public:
return pipeline;
}
void BindPipeline(VkPipeline pipeline, PipelineFlags flags) {
void BindPipeline(VkPipeline pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != VK_NULL_HANDLE);
VkRenderData data{ VKRRenderCommand::BIND_PIPELINE };
data.pipeline.pipeline = pipeline;
data.pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data);
}
void BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags) {
void BindPipeline(VKRGraphicsPipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr);
VkRenderData data{ VKRRenderCommand::BIND_GRAPHICS_PIPELINE };
data.graphics_pipeline.pipeline = pipeline;
data.graphics_pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data);
}
void BindPipeline(VKRComputePipeline *pipeline, PipelineFlags flags) {
void BindPipeline(VKRComputePipeline *pipeline, PipelineFlags flags, VkPipelineLayout pipelineLayout) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr);
VkRenderData data{ VKRRenderCommand::BIND_COMPUTE_PIPELINE };
data.compute_pipeline.pipeline = pipeline;
data.compute_pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data);
}
@@ -351,7 +354,6 @@ public:
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(size + offset < 40);
VkRenderData data{ VKRRenderCommand::PUSH_CONSTANTS };
data.push.pipelineLayout = pipelineLayout;
data.push.stages = stages;
data.push.offset = offset;
data.push.size = size;
@@ -386,12 +388,11 @@ public:
curRenderStep_->render.stencilStore = VKRRenderPassStoreAction::DONT_CARE;
}
void Draw(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) {
void Draw(VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_);
VkRenderData data{ VKRRenderCommand::DRAW };
data.draw.count = count;
data.draw.offset = offset;
data.draw.pipelineLayout = layout;
data.draw.ds = descSet;
data.draw.vbuffer = vbuffer;
data.draw.voffset = voffset;
@@ -403,12 +404,11 @@ public:
curRenderStep_->render.numDraws++;
}
void DrawIndexed(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) {
void DrawIndexed(VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_);
VkRenderData data{ VKRRenderCommand::DRAW_INDEXED };
data.drawIndexed.count = count;
data.drawIndexed.instances = numInstances;
data.drawIndexed.pipelineLayout = layout;
data.drawIndexed.ds = descSet;
data.drawIndexed.vbuffer = vbuffer;
data.drawIndexed.voffset = voffset;
+5 -5
View File
@@ -1339,7 +1339,7 @@ void VKContext::Draw(int vertexCount, int offset) {
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount, offset);
renderManager_.Draw(descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount, offset);
}
void VKContext::DrawIndexed(int vertexCount, int offset) {
@@ -1359,7 +1359,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) {
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.DrawIndexed(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16);
renderManager_.DrawIndexed(descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16);
}
void VKContext::DrawUP(const void *vdata, int vertexCount) {
@@ -1375,15 +1375,15 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) {
BindCompatiblePipeline();
ApplyDynamicState();
renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount);
renderManager_.Draw(descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount);
}
void VKContext::BindCompatiblePipeline() {
VkRenderPass renderPass = renderManager_.GetCompatibleRenderPass();
if (renderPass == renderManager_.GetBackbufferRenderPass()) {
renderManager_.BindPipeline(curPipeline_->backbufferPipeline, curPipeline_->flags);
renderManager_.BindPipeline(curPipeline_->backbufferPipeline, curPipeline_->flags, pipelineLayout_);
} else {
renderManager_.BindPipeline(curPipeline_->framebufferPipeline, curPipeline_->flags);
renderManager_.BindPipeline(curPipeline_->framebufferPipeline, curPipeline_->flags, pipelineLayout_);
}
}
+4 -3
View File
@@ -44,15 +44,16 @@
#include "Common/Buffer.h"
#include "Common/StringUtils.h"
void truncate_cpy(char *dest, size_t destSize, const char *src) {
size_t truncate_cpy(char *dest, size_t destSize, const char *src) {
size_t len = strlen(src);
if (len >= destSize - 1) {
memcpy(dest, src, destSize - 1);
dest[destSize - 1] = '\0';
len = destSize - 1;
} else {
memcpy(dest, src, len);
dest[len] = '\0';
}
dest[len] = '\0';
return len;
}
const char* safe_string(const char* s) {
+3 -3
View File
@@ -78,10 +78,10 @@ std::string ReplaceAll(std::string input, const std::string& src, const std::str
void SkipSpace(const char **ptr);
void truncate_cpy(char *dest, size_t destSize, const char *src);
size_t truncate_cpy(char *dest, size_t destSize, const char *src);
template<size_t Count>
inline void truncate_cpy(char(&out)[Count], const char *src) {
truncate_cpy(out, Count, src);
inline size_t truncate_cpy(char(&out)[Count], const char *src) {
return truncate_cpy(out, Count, src);
}
const char* safe_string(const char* s);
+34 -20
View File
@@ -37,7 +37,8 @@ public:
bool Mark(uint32_t addr, uint32_t size, uint64_t ticks, uint32_t pc, bool allocated, const char *tag);
bool Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::vector<MemBlockInfo> &results);
bool FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size, std::string &result);
// Note that the returned pointer gets invalidated as soon as Mark is called.
const char *FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size);
void Reset();
void DoState(PointerWrap &p);
@@ -151,17 +152,16 @@ bool MemSlabMap::Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::ve
return found;
}
bool MemSlabMap::FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size, std::string &result) {
const char *MemSlabMap::FastFindWriteTag(MemBlockFlags flags, uint32_t addr, uint32_t size) {
uint32_t end = addr + size;
Slab *slab = FindSlab(addr);
while (slab != nullptr && slab->start < end) {
if (slab->pc != 0 || slab->tag[0] != '\0') {
result = slab->tag;
return true;
return slab->tag;
}
slab = slab->next;
}
return false;
return nullptr;
}
void MemSlabMap::Reset() {
@@ -485,7 +485,7 @@ std::vector<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start,
return results;
}
static std::string FindWriteTagByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) {
static const char *FindWriteTagByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) {
start &= ~0xC0000000;
if (pendingNotifyMinAddr1 < start + size && pendingNotifyMaxAddr1 >= start)
@@ -493,37 +493,51 @@ static std::string FindWriteTagByFlag(MemBlockFlags flags, uint32_t start, uint3
if (pendingNotifyMinAddr2 < start + size && pendingNotifyMaxAddr2 >= start)
FlushPendingMemInfo();
std::string tag;
if (flags & MemBlockFlags::ALLOC) {
if (allocMap.FastFindWriteTag(MemBlockFlags::ALLOC, start, size, tag))
const char *tag = allocMap.FastFindWriteTag(MemBlockFlags::ALLOC, start, size);
if (tag)
return tag;
}
if (flags & MemBlockFlags::SUB_ALLOC) {
if (suballocMap.FastFindWriteTag(MemBlockFlags::SUB_ALLOC, start, size, tag))
const char *tag = suballocMap.FastFindWriteTag(MemBlockFlags::SUB_ALLOC, start, size);
if (tag)
return tag;
}
if (flags & MemBlockFlags::WRITE) {
if (writeMap.FastFindWriteTag(MemBlockFlags::WRITE, start, size, tag))
const char *tag = writeMap.FastFindWriteTag(MemBlockFlags::WRITE, start, size);
if (tag)
return tag;
}
if (flags & MemBlockFlags::TEXTURE) {
if (textureMap.FastFindWriteTag(MemBlockFlags::TEXTURE, start, size, tag))
const char *tag = textureMap.FastFindWriteTag(MemBlockFlags::TEXTURE, start, size);
if (tag)
return tag;
}
return "";
return nullptr;
}
std::string GetMemWriteTagAt(uint32_t start, uint32_t size) {
std::string tag = FindWriteTagByFlag(MemBlockFlags::WRITE, start, size);
if (!tag.empty() && tag != "MemInit")
return tag;
std::string GetMemWriteTagAt(const char *prefix, uint32_t start, uint32_t size) {
const char *tag = FindWriteTagByFlag(MemBlockFlags::WRITE, start, size);
if (tag && strcmp(tag, "MemInit") != 0)
return std::string(prefix) + tag;
// Fall back to alloc and texture, especially for VRAM. We prefer write above.
tag = FindWriteTagByFlag(MemBlockFlags::ALLOC | MemBlockFlags::TEXTURE, start, size);
if (!tag.empty())
return tag;
if (tag)
return std::string(prefix) + tag;
return StringFromFormat("%s%08x_size_%08x", prefix, start, size);
}
return StringFromFormat("%08x_size_%08x", start, size);
size_t FormatMemWriteTagAt(char *buf, size_t sz, const char *prefix, uint32_t start, uint32_t size) {
const char *tag = FindWriteTagByFlag(MemBlockFlags::WRITE, start, size);
if (tag && strcmp(tag, "MemInit") != 0) {
return snprintf(buf, sz, "%s%s", prefix, tag);
}
// Fall back to alloc and texture, especially for VRAM. We prefer write above.
tag = FindWriteTagByFlag(MemBlockFlags::ALLOC | MemBlockFlags::TEXTURE, start, size);
if (tag) {
return snprintf(buf, sz, "%s%s", prefix, tag);
}
return snprintf(buf, sz, "%s%08x_size_%08x", prefix, start, size);
}
void MemBlockInfoInit() {
+3 -1
View File
@@ -68,7 +68,9 @@ inline void NotifyMemInfo(MemBlockFlags flags, uint32_t start, uint32_t size, co
std::vector<MemBlockInfo> FindMemInfo(uint32_t start, uint32_t size);
std::vector<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size);
std::string GetMemWriteTagAt(uint32_t start, uint32_t size);
std::string GetMemWriteTagAt(const char *prefix, uint32_t start, uint32_t size);
// Same as above but allocation-free.
size_t FormatMemWriteTagAt(char *buf, size_t sz, const char *prefix, uint32_t start, uint32_t size);
void MemBlockInfoInit();
void MemBlockInfoShutdown();
+1 -1
View File
@@ -129,6 +129,6 @@ protected:
private:
DialogStatus status = SCE_UTILITY_STATUS_NONE;
UtilityDialogType dialogType_;
UtilityDialogType dialogType_ = UtilityDialogType::NONE;
bool volatileLocked_ = false;
};
-3
View File
@@ -285,9 +285,6 @@ struct SaveFileInfo
PPGeImage *texture = nullptr;
SaveFileInfo() {
}
void DoState(PointerWrap &p);
};
+5 -5
View File
@@ -159,7 +159,7 @@ static int Replace_memcpy() {
RETURN(destPtr);
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
const std::string tag = GetMemWriteTagAt("ReplaceMemcpy/", srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
@@ -211,7 +211,7 @@ static int Replace_memcpy_jak() {
RETURN(destPtr);
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemcpy/" + GetMemWriteTagAt(srcPtr, bytes);
const std::string tag = GetMemWriteTagAt("ReplaceMemcpy/", srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
@@ -249,7 +249,7 @@ static int Replace_memcpy16() {
RETURN(destPtr);
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemcpy16/" + GetMemWriteTagAt(srcPtr, bytes);
const std::string tag = GetMemWriteTagAt("ReplaceMemcpy16/", srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
}
@@ -290,7 +290,7 @@ static int Replace_memcpy_swizzled() {
RETURN(0);
if (MemBlockInfoDetailed(pitch * h)) {
const std::string tag = "ReplaceMemcpySwizzle/" + GetMemWriteTagAt(srcPtr, pitch * h);
const std::string tag = GetMemWriteTagAt("ReplaceMemcpySwizzle/", srcPtr, pitch * h);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, pitch * h, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, pitch * h, tag.c_str(), tag.size());
}
@@ -321,7 +321,7 @@ static int Replace_memmove() {
RETURN(destPtr);
if (MemBlockInfoDetailed(bytes)) {
const std::string tag = "ReplaceMemmove/" + GetMemWriteTagAt(srcPtr, bytes);
const std::string tag = GetMemWriteTagAt("ReplaceMemmove/", srcPtr, bytes);
NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, tag.c_str(), tag.size());
}
+13 -11
View File
@@ -64,8 +64,8 @@ int srcFrequency = 0;
const int hwSampleRate = 44100;
int hwBlockSize = 64;
int hostAttemptBlockSize = 512;
const int hwBlockSize = 64;
const int hostAttemptBlockSize = 512;
static int audioIntervalCycles;
static int audioHostIntervalCycles;
@@ -82,6 +82,11 @@ static bool m_logAudio;
static int chanQueueMaxSizeFactor;
static int chanQueueMinSizeFactor;
// Accessor for libretro
int __AudioGetHostAttemptBlockSize() {
return hostAttemptBlockSize;
}
static void hleAudioUpdate(u64 userdata, int cyclesLate) {
// Schedule the next cycle first. __AudioUpdate() may consume cycles.
CoreTiming::ScheduleEvent(audioIntervalCycles - cyclesLate, eventAudioUpdate, 0);
@@ -110,8 +115,6 @@ void __AudioInit() {
chanQueueMaxSizeFactor = 2;
chanQueueMinSizeFactor = 1;
hwBlockSize = 64;
hostAttemptBlockSize = 512;
__AudioCPUMHzChange();
@@ -338,7 +341,8 @@ void __AudioUpdate(bool resetRecording) {
// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
// if the buffer somehow gets full.
bool firstChannel = true;
std::vector<int16_t> srcBuffer;
const int16_t srcBufferSize = hwBlockSize * 2;
int16_t srcBuffer[srcBufferSize];
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) {
if (!chans[i].reserved)
@@ -351,7 +355,7 @@ void __AudioUpdate(bool resetRecording) {
}
bool needsResample = i == PSP_AUDIO_CHANNEL_SRC && srcFrequency != 0 && srcFrequency != mixFrequency;
size_t sz = needsResample ? (hwBlockSize * 2 * srcFrequency) / mixFrequency : hwBlockSize * 2;
size_t sz = needsResample ? (srcBufferSize * srcFrequency) / mixFrequency : srcBufferSize;
if (sz > chanSampleQueues[i].size()) {
ERROR_LOG(SCEAUDIO, "Channel %i buffer underrun at %i of %i", i, (int)chanSampleQueues[i].size() / 2, (int)sz / 2);
}
@@ -372,13 +376,11 @@ void __AudioUpdate(bool resetRecording) {
return buf1[sz1 - 1];
};
srcBuffer.resize(hwBlockSize * 2);
// TODO: This is terrible, since it's doing it by small chunk and discarding frac.
const uint32_t ratio = (uint32_t)(65536.0 * srcFrequency / (double)mixFrequency);
uint32_t frac = 0;
size_t readIndex = 0;
for (size_t outIndex = 0; readIndex < sz && outIndex < srcBuffer.size(); outIndex += 2) {
for (size_t outIndex = 0; readIndex < sz && outIndex < srcBufferSize; outIndex += 2) {
size_t readIndex2 = readIndex + 2;
int16_t l1 = read(readIndex);
int16_t r1 = read(readIndex + 1);
@@ -393,8 +395,8 @@ void __AudioUpdate(bool resetRecording) {
frac &= 0xffff;
}
buf1 = srcBuffer.data();
sz1 = srcBuffer.size();
buf1 = srcBuffer;
sz1 = srcBufferSize;
buf2 = nullptr;
sz2 = 0;
}
+2
View File
@@ -50,6 +50,8 @@ int __AudioMix(short *outstereo, int numSamples, int sampleRate);
void __AudioGetDebugStats(char *buf, size_t bufSize);
void __PushExternalAudio(const s32 *audio, int numSamples); // Should not be used in-game, only at the menu!
int __AudioGetHostAttemptBlockSize();
// Audio Dumping stuff
void __StartLogAudio(const Path &filename);
void __StopLogAudio();
+1 -1
View File
@@ -1268,7 +1268,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3
if (outbufPtr != 0) {
u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16);
if (packetAddr != 0 && MemBlockInfoDetailed()) {
const std::string tag = "AtracDecode/" + GetMemWriteTagAt(packetAddr, packetSize);
const std::string tag = GetMemWriteTagAt("AtracDecode/", packetAddr, packetSize);
NotifyMemInfo(MemBlockFlags::READ, packetAddr, packetSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, tag.c_str(), tag.size());
} else {
+1 -1
View File
@@ -59,7 +59,7 @@ static int CommonDecompress(int windowBits, u32 OutBuffer, int OutBufferLength,
}
if (MemBlockInfoDetailed(stream.total_in, stream.total_out)) {
const std::string tag = "sceDeflt/" + GetMemWriteTagAt(InBuffer, stream.total_in);
const std::string tag = GetMemWriteTagAt("sceDeflt/", InBuffer, stream.total_in);
NotifyMemInfo(MemBlockFlags::READ, InBuffer, stream.total_in, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, OutBuffer, stream.total_out, tag.c_str(), tag.size());
}
+1 -1
View File
@@ -52,7 +52,7 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) {
if (!skip) {
currentMIPS->InvalidateICache(src, size);
if (MemBlockInfoDetailed(size)) {
const std::string tag = "DmacMemcpy/" + GetMemWriteTagAt(src, size);
const std::string tag = GetMemWriteTagAt("DmacMemcpy/", src, size);
Memory::Memcpy(dst, src, size, tag.c_str(), tag.size());
} else {
Memory::Memcpy(dst, src, size, "DmacMemcpy");
+3 -3
View File
@@ -656,7 +656,7 @@ static u32 sceKernelMemcpy(u32 dst, u32 src, u32 size)
}
if (MemBlockInfoDetailed(size)) {
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
const std::string tag = GetMemWriteTagAt("KernelMemcpy/", src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
}
@@ -691,7 +691,7 @@ static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) {
memcpy(Memory::GetPointerWriteUnchecked(dst), Memory::GetPointerUnchecked(src), size);
}
if (MemBlockInfoDetailed(size)) {
const std::string tag = "KernelMemcpy/" + GetMemWriteTagAt(src, size);
const std::string tag = GetMemWriteTagAt("KernelMemcpy/", src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
}
@@ -794,7 +794,7 @@ static u32 sysclib_memmove(u32 dst, u32 src, u32 size) {
memmove(Memory::GetPointerWriteUnchecked(dst), Memory::GetPointerUnchecked(src), size);
}
if (MemBlockInfoDetailed(size)) {
const std::string tag = "KernelMemmove/" + GetMemWriteTagAt(src, size);
const std::string tag = GetMemWriteTagAt("KernelMemmove/", src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, size, tag.c_str(), tag.size());
}
+3 -2
View File
@@ -20,6 +20,7 @@
#include <cstring>
#include "Common/CommonTypes.h"
#include "Common/StringUtils.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/MemMap.h"
#include "Core/MIPS/MIPS.h"
@@ -70,9 +71,9 @@ inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len,
if (MemBlockInfoDetailed(len)) {
char tagData[128];
if (!tag) {
const std::string srcTag = GetMemWriteTagAt(from_address, len);
const std::string srcTag = GetMemWriteTagAt("Memcpy/", from_address, len);
tag = tagData;
tagLen = snprintf(tagData, sizeof(tagData), "Memcpy/%s", srcTag.c_str());
tagLen = truncate_cpy(tagData, srcTag.c_str());
}
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag, tagLen);
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag, tagLen);
+2 -3
View File
@@ -701,12 +701,11 @@ void DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti
DeferredDrawCall &dc = drawCalls[numDrawCalls];
dc.verts = verts;
dc.inds = inds;
dc.vertexCount = vertexCount;
dc.indexType = (vertTypeID & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT;
dc.prim = prim;
dc.vertexCount = vertexCount;
dc.uvScale = gstate_c.uv;
dc.cullMode = cullMode;
dc.uvScale = gstate_c.uv;
if (inds) {
GetIndexBounds(inds, vertexCount, vertTypeID, &dc.indexLowerBound, &dc.indexUpperBound);
} else {
+1 -1
View File
@@ -165,10 +165,10 @@ protected:
u32 vertexCount;
u8 indexType;
s8 prim;
u8 cullMode;
u16 indexLowerBound;
u16 indexUpperBound;
UVScale uvScale;
int cullMode;
};
enum { MAX_DEFERRED_DRAW_CALLS = 128 };
+1 -1
View File
@@ -905,7 +905,6 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer
}
void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb) {
// ugly...
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) {
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE);
}
@@ -922,6 +921,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe
} else {
DownloadFramebufferOnSwitch(prevVfb);
}
textureCache_->ForgetLastTexture();
shaderManager_->DirtyLastShader();
+14 -13
View File
@@ -21,6 +21,7 @@
#include "Common/Common.h"
#include "Common/Data/Convert/ColorConv.h"
#include "Common/Data/Collections/TinySet.h"
#include "Common/Profiler/Profiler.h"
#include "Common/MemoryUtil.h"
#include "Common/StringUtils.h"
@@ -616,18 +617,18 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
bool TextureCacheCommon::GetBestFramebufferCandidate(const TextureDefinition &entry, u32 texAddrOffset, AttachCandidate *bestCandidate) const {
gpuStats.numFramebufferEvaluations++;
std::vector<AttachCandidate> candidates;
TinySet<AttachCandidate, 6> candidates;
const std::vector<VirtualFramebuffer *> &framebuffers = framebufferManager_->Framebuffers();
for (VirtualFramebuffer *framebuffer : framebuffers) {
FramebufferMatchInfo match{};
if (MatchFramebuffer(entry, framebuffer, texAddrOffset, RASTER_COLOR, &match)) {
candidates.push_back(AttachCandidate{ match, entry, framebuffer, RASTER_COLOR, framebuffer->colorBindSeq });
candidates.push_back(AttachCandidate{ framebuffer, match, RASTER_COLOR });
}
match = {};
if (MatchFramebuffer(entry, framebuffer, texAddrOffset, RASTER_DEPTH, &match)) {
candidates.push_back(AttachCandidate{ match, entry, framebuffer, RASTER_DEPTH, framebuffer->depthBindSeq });
candidates.push_back(AttachCandidate{ framebuffer, match, RASTER_DEPTH });
}
}
@@ -640,11 +641,11 @@ bool TextureCacheCommon::GetBestFramebufferCandidate(const TextureDefinition &en
if (Reporting::ShouldLogNTimes("multifbcandidate", 5)) {
std::string cands;
for (auto &candidate : candidates) {
cands += candidate.ToString() + "\n";
}
for (size_t i = 0; i < candidates.size(); i++) {
cands += candidates[i].ToString() + "\n";
}
WARN_LOG_N_TIMES(multifbcandidate, 5, G3D, "GetFramebufferCandidates: Multiple (%d) candidate framebuffers. texaddr: %08x offset: %d (%dx%d stride %d, %s):\n%s",
WARN_LOG(G3D, "GetFramebufferCandidates: Multiple (%d) candidate framebuffers. texaddr: %08x offset: %d (%dx%d stride %d, %s):\n%s",
(int)candidates.size(),
entry.addr, texAddrOffset, dimWidth(entry.dim), dimHeight(entry.dim), entry.bufw, GeTextureFormatToString(entry.format),
cands.c_str()
@@ -653,17 +654,17 @@ bool TextureCacheCommon::GetBestFramebufferCandidate(const TextureDefinition &en
// OK, multiple possible candidates. Will need to figure out which one is the most relevant.
int bestRelevancy = -1;
int bestIndex = -1;
size_t bestIndex = -1;
bool kzCompat = PSP_CoreParameter().compat.flags().SplitFramebufferMargin;
// We simply use the sequence counter as relevancy nowadays.
for (int i = 0; i < (int)candidates.size(); i++) {
for (size_t i = 0; i < candidates.size(); i++) {
const AttachCandidate &candidate = candidates[i];
int relevancy = candidate.seqCount;
int relevancy = candidate.channel == RASTER_COLOR ? candidate.fb->colorBindSeq : candidate.fb->depthBindSeq;
// Add a small negative penalty if the texture is currently bound as a framebuffer, and offset is not zero.
// Should avoid problems when pingponging two nearby buffers, like in Wipeout Pure in #15927
// Should avoid problems when pingponging two nearby buffers, like in Wipeout Pure in #15927.
if (candidate.channel == RASTER_COLOR &&
(candidate.match.yOffset != 0 || candidate.match.xOffset != 0) &&
(candidate.fb->fb_address & 0x1FFFFF) == (gstate.getFrameBufAddress() & 0x1FFFFF)) {
@@ -865,7 +866,7 @@ bool TextureCacheCommon::MatchFramebuffer(
uint32_t fb_stride = channel == RASTER_DEPTH ? framebuffer->z_stride : framebuffer->fb_stride;
GEBufferFormat fb_format = channel == RASTER_DEPTH ? GE_FORMAT_DEPTH16 : framebuffer->fb_format;
if (channel == RASTER_DEPTH && framebuffer->z_address == framebuffer->fb_address) {
if (channel == RASTER_DEPTH && (framebuffer->z_address == framebuffer->fb_address || framebuffer->z_address == 0)) {
// Try to avoid silly matches to somewhat malformed buffers.
return false;
}
@@ -2248,7 +2249,7 @@ void TextureCacheCommon::ClearNextFrame() {
std::string AttachCandidate::ToString() const {
return StringFromFormat("[%s seq:%d C:%08x/%d(%s) Z:%08x/%d X:%d Y:%d reint: %s]",
this->channel == RASTER_COLOR ? "COLOR" : "DEPTH",
this->seqCount,
this->channel == RASTER_COLOR ? this->fb->colorBindSeq : this->fb->depthBindSeq,
this->fb->fb_address, this->fb->fb_stride, GeBufferFormatToString(this->fb->fb_format),
this->fb->z_address, this->fb->z_stride,
this->match.xOffset, this->match.yOffset, this->match.reinterpret ? "true" : "false");
+5 -8
View File
@@ -93,12 +93,11 @@ class VulkanTexture;
// Enough information about a texture to match it to framebuffers.
struct TextureDefinition {
u32 addr;
u16 bufw;
u16 dim;
GETextureFormat format;
u32 dim;
u32 bufw;
};
// TODO: Shrink this struct. There is some fluff.
// NOTE: These only handle textures loaded directly from PSP memory contents.
@@ -209,18 +208,16 @@ typedef std::map<u64, std::unique_ptr<TexCacheEntry>> TexCache;
#endif
struct FramebufferMatchInfo {
int xOffset;
int yOffset;
int16_t xOffset;
int16_t yOffset;
bool reinterpret;
GEBufferFormat reinterpretTo;
};
struct AttachCandidate {
FramebufferMatchInfo match;
TextureDefinition entry;
VirtualFramebuffer *fb;
FramebufferMatchInfo match;
RasterChannel channel;
int seqCount;
std::string ToString() const;
};
-3
View File
@@ -176,9 +176,6 @@ void PrintDecodedVertex(VertexReader &vtx) {
printf("P: %f %f %f\n", pos[0], pos[1], pos[2]);
}
VertexDecoder::VertexDecoder() : decoded_(nullptr), ptr_(nullptr), jitted_(0), jittedSize_(0) {
}
void VertexDecoder::Step_WeightsU8() const
{
u8 *wt = (u8 *)(decoded_ + decFmt.w0off);
+10 -10
View File
@@ -125,10 +125,13 @@ public:
case DEC_FLOAT_3:
{
const float *f = (const float *)(data_ + decFmt_.posoff);
memcpy(pos, f, 12);
if (isThrough()) {
pos[0] = f[0];
pos[1] = f[1];
if (!isThrough()) {
pos[2] = f[2];
} else {
// Integer value passed in a float. Clamped to 0, 65535.
const float z = (int)pos[2] * (1.0f / 65535.0f);
const float z = (int)f[2] * (1.0f / 65535.0f);
pos[2] = z > 1.0f ? 1.0f : (z < 0.0f ? 0.0f : z);
}
}
@@ -443,8 +446,6 @@ struct VertexDecoderOptions {
class VertexDecoder {
public:
VertexDecoder();
// A jit cache is not mandatory.
void SetVertexType(u32 vtype, const VertexDecoderOptions &options, VertexDecoderJitCache *jitCache = nullptr);
@@ -549,11 +550,10 @@ public:
int ToString(char *output) const;
// Mutable decoder state
mutable u8 *decoded_;
mutable const u8 *ptr_;
JittedVertexDecoder jitted_;
int32_t jittedSize_;
mutable u8 *decoded_ = nullptr;
mutable const u8 *ptr_ = nullptr;
JittedVertexDecoder jitted_ = 0;
int32_t jittedSize_ = 0;
// "Immutable" state, set at startup
+6 -5
View File
@@ -2864,9 +2864,10 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) {
if (MemBlockInfoDetailed(numBytes, numBytes)) {
const uint32_t src = srcBasePtr + (srcY * srcStride + srcX) * bpp;
const uint32_t dst = dstBasePtr + (dstY * dstStride + dstX) * bpp;
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag.c_str(), tag.size());
char tag[128];
size_t tagSize = FormatMemWriteTagAt(tag, sizeof(tag), "GPUBlockTransfer/", src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag, tagSize);
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag, tagSize);
}
// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
@@ -2881,7 +2882,7 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
// Since they're identical we don't need to copy.
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
if (MemBlockInfoDetailed(size)) {
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
const std::string tag = GetMemWriteTagAt("GPUMemcpy/", src, size);
Memory::Memcpy(dest, src, size, tag.c_str(), tag.size());
} else {
Memory::Memcpy(dest, src, size, "GPUMemcpy");
@@ -2893,7 +2894,7 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
}
if (MemBlockInfoDetailed(size)) {
const std::string tag = "GPUMemcpy/" + GetMemWriteTagAt(src, size);
const std::string tag = GetMemWriteTagAt("GPUMemcpy/", src, size);
NotifyMemInfo(MemBlockFlags::READ, src, size, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, tag.c_str(), tag.size());
}
+1 -1
View File
@@ -813,7 +813,7 @@ void SoftGPU::Execute_BlockTransferStart(u32 op, u32 diff) {
}
if (MemBlockInfoDetailed(srcSize, dstSize)) {
const std::string tag = "GPUBlockTransfer/" + GetMemWriteTagAt(src, srcSize);
const std::string tag = GetMemWriteTagAt("GPUBlockTransfer/", src, srcSize);
NotifyMemInfo(MemBlockFlags::READ, src, srcSize, tag.c_str(), tag.size());
NotifyMemInfo(MemBlockFlags::WRITE, dst, dstSize, tag.c_str(), tag.size());
}
+6 -6
View File
@@ -787,7 +787,7 @@ void DrawEngineVulkan::DoFlush() {
lastRenderStepId_ = curRenderStepId;
}
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags);
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags, pipelineLayout_);
if (pipeline != lastPipeline_) {
if (lastPipeline_ && !(lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant())) {
gstate_c.Dirty(DIRTY_BLEND_STATE);
@@ -814,9 +814,9 @@ void DrawEngineVulkan::DoFlush() {
if (!ibuf) {
ibOffset = (uint32_t)frameData.pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &ibuf);
}
renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1, VK_INDEX_TYPE_UINT16);
renderManager->DrawIndexed(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1, VK_INDEX_TYPE_UINT16);
} else {
renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount);
renderManager->Draw(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount);
}
} else {
PROFILE_THIS_SCOPE("soft");
@@ -917,7 +917,7 @@ void DrawEngineVulkan::DoFlush() {
lastRenderStepId_ = curRenderStepId;
}
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags);
renderManager->BindPipeline(pipeline->pipeline, (PipelineFlags)pipeline->flags, pipelineLayout_);
if (pipeline != lastPipeline_) {
if (lastPipeline_ && !lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant()) {
gstate_c.Dirty(DIRTY_BLEND_STATE);
@@ -949,11 +949,11 @@ void DrawEngineVulkan::DoFlush() {
VkBuffer vbuf, ibuf;
vbOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, maxIndex * sizeof(TransformedVertex), &vbuf);
ibOffset = (uint32_t)frameData.pushIndex->Push(inds, sizeof(short) * result.drawNumTrans, &ibuf);
renderManager->DrawIndexed(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, result.drawNumTrans, 1, VK_INDEX_TYPE_UINT16);
renderManager->DrawIndexed(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, result.drawNumTrans, 1, VK_INDEX_TYPE_UINT16);
} else {
VkBuffer vbuf;
vbOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, result.drawNumTrans * sizeof(TransformedVertex), &vbuf);
renderManager->Draw(pipelineLayout_, ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, result.drawNumTrans);
renderManager->Draw(ds, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, result.drawNumTrans);
}
} else if (result.action == SW_CLEAR) {
// Note: we won't get here if the clear is alpha but not color, or color but not alpha.
+1 -1
View File
@@ -405,7 +405,7 @@ enum GELightComputation
GE_LIGHTCOMP_ONLYPOWDIFFUSE = 2,
};
enum GETextureFormat
enum GETextureFormat : uint8_t
{
GE_TFMT_5650 = 0,
GE_TFMT_5551 = 1,
+1 -1
View File
@@ -379,7 +379,7 @@ class LibretroHost : public Host
void InitSound() override {}
void UpdateSound() override
{
extern int hostAttemptBlockSize;
int hostAttemptBlockSize = __AudioGetHostAttemptBlockSize();
const int blockSizeMax = 512;
static int16_t audio[blockSizeMax * 2];
assert(hostAttemptBlockSize <= blockSizeMax);
+40
View File
@@ -40,6 +40,7 @@
#include <jni.h>
#endif
#include "Common/Data/Collections/TinySet.h"
#include "Common/Data/Text/Parsers.h"
#include "Common/Data/Text/WrapText.h"
#include "Common/Data/Encoding/Utf8.h"
@@ -308,6 +309,44 @@ bool TestParsers() {
return true;
}
bool TestTinySet() {
TinySet<int, 4> a;
EXPECT_EQ_INT((int)a.size(), 0);
a.push_back(1);
EXPECT_EQ_INT((int)a.size(), 1);
a.push_back(2);
EXPECT_EQ_INT((int)a.size(), 2);
TinySet<int, 4> b;
b.push_back(8);
b.push_back(9);
b.push_back(10);
EXPECT_EQ_INT((int)b.size(), 3);
a.append(b);
EXPECT_EQ_INT((int)a.size(), 5);
EXPECT_EQ_INT((int)b.size(), 3);
b.append(b);
EXPECT_EQ_INT((int)b.size(), 6);
EXPECT_EQ_INT(a[0], 1);
EXPECT_EQ_INT(a[1], 2);
EXPECT_EQ_INT(a[2], 8);
EXPECT_EQ_INT(a[3], 9);
EXPECT_EQ_INT(a[4], 10);
a.append(a);
EXPECT_EQ_INT(a.size(), 10);
EXPECT_EQ_INT(a[9], 10);
b.push_back(11);
EXPECT_EQ_INT((int)b.size(), 7);
b.push_back(12);
EXPECT_EQ_INT((int)b.size(), 8);
b.push_back(13);
EXPECT_EQ_INT(b.size(), 9);
return true;
}
bool TestVFPUSinCos() {
float sine, cosine;
InitVFPUSinCos();
@@ -792,6 +831,7 @@ TestItem availableTests[] = {
TEST_ITEM(AndroidContentURI),
TEST_ITEM(ThreadManager),
TEST_ITEM(WrapText),
TEST_ITEM(TinySet),
};
int main(int argc, const char *argv[]) {