mirror of
https://github.com/rt64/rt64.git
synced 2025-03-14 13:21:24 +00:00
Optimize render encoder end/start
This commit is contained in:
parent
49929ab728
commit
9efb1ab743
@ -1075,7 +1075,7 @@ namespace RT64 {
|
||||
ctx.commandList->setGraphicsPushConstants(0, &pushConstant1);
|
||||
drawRasterTriangle(ctx);
|
||||
|
||||
// Draw second triangle with push constants for red color
|
||||
// Draw third triangle with push constants for green color
|
||||
offsetViewport.y -= 100.0f;
|
||||
ctx.commandList->setViewports(offsetViewport);
|
||||
RasterPushConstant pushConstant2;
|
||||
@ -1416,7 +1416,7 @@ namespace RT64 {
|
||||
using TestSetupFunc = std::function<std::unique_ptr<TestBase>()>;
|
||||
static std::vector<TestSetupFunc> g_Tests;
|
||||
static std::unique_ptr<TestBase> g_CurrentTest;
|
||||
static uint32_t g_CurrentTestIndex = 2;
|
||||
static uint32_t g_CurrentTestIndex = 1;
|
||||
|
||||
void RegisterTests() {
|
||||
g_Tests.push_back([]() { return std::make_unique<ClearTest>(); });
|
||||
|
@ -90,6 +90,14 @@ struct SamplePosition
|
||||
|
||||
float x;
|
||||
float y;
|
||||
|
||||
bool operator==(const SamplePosition& other) const {
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
bool operator!=(const SamplePosition& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
} _MTL_PACKED;
|
||||
|
||||
struct ResourceID
|
||||
|
@ -536,7 +536,6 @@ namespace RT64 {
|
||||
state->winding = MTL::WindingClockwise;
|
||||
state->sampleCount = desc.multisampling.sampleCount;
|
||||
if (desc.multisampling.sampleCount > 1) {
|
||||
state->samplePositions = new MTL::SamplePosition[desc.multisampling.sampleCount];
|
||||
for (uint32_t i = 0; i < desc.multisampling.sampleCount; i++) {
|
||||
state->samplePositions[i] = { (float)desc.multisampling.sampleLocations[i].x, (float)desc.multisampling.sampleLocations[i].y };
|
||||
}
|
||||
@ -562,8 +561,6 @@ namespace RT64 {
|
||||
MetalGraphicsPipeline::~MetalGraphicsPipeline() {
|
||||
state->renderPipelineState->release();
|
||||
state->depthStencilState->release();
|
||||
// TODO: better way to dispose of sample positions
|
||||
delete[] state->samplePositions;
|
||||
delete state;
|
||||
}
|
||||
|
||||
@ -1195,8 +1192,15 @@ namespace RT64 {
|
||||
case MetalPipeline::Type::Graphics: {
|
||||
const auto *graphicsPipeline = static_cast<const MetalGraphicsPipeline *>(interfacePipeline);
|
||||
if (activeRenderState) {
|
||||
if (activeRenderState->samplePositions != graphicsPipeline->state->samplePositions || activeRenderState->sampleCount != graphicsPipeline->state->sampleCount) {
|
||||
if (activeRenderState->sampleCount != graphicsPipeline->state->sampleCount) {
|
||||
endActiveRenderEncoder();
|
||||
} else if (activeRenderState->sampleCount > 1) {
|
||||
for (uint32_t i = 0; i < activeRenderState->sampleCount; i++) {
|
||||
if (activeRenderState->samplePositions[i] != graphicsPipeline->state->samplePositions[i]) {
|
||||
endActiveRenderEncoder();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1400,17 +1404,23 @@ namespace RT64 {
|
||||
}
|
||||
|
||||
void MetalCommandList::setFramebuffer(const RenderFramebuffer *framebuffer) {
|
||||
// If we're changing framebuffers, we need to end current encoder and reset state
|
||||
if (targetFramebuffer != framebuffer) {
|
||||
endOtherEncoders(EncoderType::Render);
|
||||
endActiveRenderEncoder();
|
||||
|
||||
targetFramebuffer = static_cast<const MetalFramebuffer*>(framebuffer);
|
||||
|
||||
// Mark all state as needing update with the new encoder
|
||||
if (targetFramebuffer != nullptr) {
|
||||
dirtyGraphicsState.setAll();
|
||||
endOtherEncoders(EncoderType::Render);
|
||||
|
||||
if (framebuffer != nullptr) {
|
||||
auto incomingFramebuffer = static_cast<const MetalFramebuffer*>(framebuffer);
|
||||
|
||||
// check if we need to end the current encoder
|
||||
if (targetFramebuffer == nullptr || *targetFramebuffer != *incomingFramebuffer) {
|
||||
endActiveRenderEncoder();
|
||||
targetFramebuffer = incomingFramebuffer;
|
||||
|
||||
// Mark all state as needing update with the new encoder
|
||||
if (targetFramebuffer != nullptr) {
|
||||
dirtyGraphicsState.setAll();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
targetFramebuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ namespace RT64 {
|
||||
struct MetalGraphicsPipeline;
|
||||
struct MetalPool;
|
||||
struct MetalDrawable;
|
||||
struct ExtendedRenderTexture;
|
||||
|
||||
enum class EncoderType {
|
||||
Render,
|
||||
@ -92,7 +91,7 @@ namespace RT64 {
|
||||
MTL::CullMode cullMode = MTL::CullModeNone;
|
||||
MTL::DepthClipMode depthClipMode = MTL::DepthClipModeClip;
|
||||
MTL::Winding winding = MTL::WindingClockwise;
|
||||
MTL::SamplePosition *samplePositions = nullptr;
|
||||
MTL::SamplePosition samplePositions[16] = {};
|
||||
uint32_t sampleCount = 0;
|
||||
};
|
||||
|
||||
@ -104,6 +103,11 @@ namespace RT64 {
|
||||
: buffer(buffer), offset(offset) {}
|
||||
};
|
||||
|
||||
struct ExtendedRenderTexture: RenderTexture {
|
||||
RenderTextureDesc desc;
|
||||
virtual MTL::Texture* getTexture() const = 0;
|
||||
};
|
||||
|
||||
struct MetalDescriptorSet : RenderDescriptorSet {
|
||||
std::unordered_map<uint32_t, MTL::Texture *> indicesToTextures;
|
||||
std::unordered_map<uint32_t, MetalBufferBinding> indicesToBuffers;
|
||||
@ -164,6 +168,38 @@ namespace RT64 {
|
||||
~MetalFramebuffer() override;
|
||||
uint32_t getWidth() const override;
|
||||
uint32_t getHeight() const override;
|
||||
|
||||
// this comparison is tailored towards whether we'll require a new encoder
|
||||
bool operator==(const MetalFramebuffer& other) const {
|
||||
if (colorAttachments.size() != other.colorAttachments.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < colorAttachments.size(); i++) {
|
||||
if (colorAttachments[i]->getTexture() != other.colorAttachments[i]->getTexture() ||
|
||||
colorAttachments[i]->desc.multisampling.sampleCount != other.colorAttachments[i]->desc.multisampling.sampleCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compare individual sample locations if multisampling is enabled
|
||||
if (colorAttachments[i]->desc.multisampling.sampleCount > 1) {
|
||||
for (uint32_t s = 0; s < colorAttachments[i]->desc.multisampling.sampleCount; s++) {
|
||||
const auto& loc1 = colorAttachments[i]->desc.multisampling.sampleLocations[s];
|
||||
const auto& loc2 = other.colorAttachments[i]->desc.multisampling.sampleLocations[s];
|
||||
if (loc1 != loc2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return depthAttachment == other.depthAttachment;
|
||||
}
|
||||
|
||||
bool operator!=(const MetalFramebuffer& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct MetalCommandList : RenderCommandList {
|
||||
@ -358,11 +394,6 @@ namespace RT64 {
|
||||
~MetalBufferFormattedView() override;
|
||||
};
|
||||
|
||||
struct ExtendedRenderTexture: RenderTexture {
|
||||
RenderTextureDesc desc;
|
||||
virtual MTL::Texture* getTexture() const = 0;
|
||||
};
|
||||
|
||||
struct MetalDrawable : ExtendedRenderTexture {
|
||||
CA::MetalDrawable *mtl = nullptr;
|
||||
|
||||
|
@ -696,6 +696,14 @@ namespace RT64 {
|
||||
// Valid range is [-8, 7].
|
||||
int8_t x = 0;
|
||||
int8_t y = 0;
|
||||
|
||||
bool operator==(const RenderMultisamplingLocation& other) const {
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
bool operator!=(const RenderMultisamplingLocation& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderMultisampling {
|
||||
|
Loading…
x
Reference in New Issue
Block a user