diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp
index 2e5c0e40e..bc5d59575 100644
--- a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp
+++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp
@@ -263,8 +263,14 @@ int SoftwareIspPipelineGpu::processGPU(FrameBuffer *input, FrameBuffer *output,
 		egl_.updateInputTexture2D(*eglImageBayerIn_, inMapped->value().planes()[0].data());
 	}
 
-	/* Generate the output render framebuffer as render to texture */
-	egl_.createOutputDMABufTexture2D(*eglImageRGBAOut_, output->planes()[0].fd.get());
+	/* Find an existing eglImage in the cache */
+	auto [output_cache, output_miss] = eglImageRGBAOut_.try_emplace(output);
+	if (output_miss) {
+		/* Generate the output render framebuffer as render to texture */
+		output_cache->second = std::make_unique<eGLImage>(GL_RGBA, outputSize_.width, outputSize_.height, outputConfig_.stride, GL_TEXTURE3, 3);
+		egl_.createOutputDMABufTexture2D(*output_cache->second, output->planes()[0].fd.get());
+	}
+	eGLImage &eglImageRGBAOut = *output_cache->second;
 
 	pipelineResult = gpuIspShaderPassBlcNormalise_.process(*eglImageBayerIn_, *eglImagePingPong_[0], width_, height_, params);
 	if (pipelineResult) {
@@ -272,7 +278,7 @@ int SoftwareIspPipelineGpu::processGPU(FrameBuffer *input, FrameBuffer *output,
 		return pipelineResult;
 	}
 
-	pipelineResult = gpuIspShaderPassDemosiac_.process(*eglImagePingPong_[0], *eglImageRGBAOut_, width_, height_, params);
+	pipelineResult = gpuIspShaderPassDemosiac_.process(*eglImagePingPong_[0], eglImageRGBAOut, width_, height_, params);
 	if (pipelineResult) {
 		LOG(Debayer, Error) << "Demosiac fail";
 		return pipelineResult;
@@ -371,9 +377,6 @@ int SoftwareIspPipelineGpu::start()
 	eglImagePingPong_[0] = std::make_unique<eGLImage>(gpuIspShaderPassDemosiac_.glFormat_, width_, height_, outputConfig_.stride, GL_TEXTURE1, 1);
 	eglImagePingPong_[1] = std::make_unique<eGLImage>(gpuIspShaderPassDemosiac_.glFormat_, width_, height_, outputConfig_.stride, GL_TEXTURE2, 2);
 
-	/* Texture we will render to */
-	eglImageRGBAOut_ = std::make_unique<eGLImage>(GL_RGBA, outputSize_.width, outputSize_.height, outputConfig_.stride, GL_TEXTURE3, 3);
-
 	egl_.createInputTexture2D(*eglImageBayerIn_, NULL);
 	egl_.createOutputTexture2D(*eglImagePingPong_[0]);
 	egl_.createOutputTexture2D(*eglImagePingPong_[1]);
@@ -383,7 +386,7 @@ int SoftwareIspPipelineGpu::start()
 
 void SoftwareIspPipelineGpu::stop()
 {
-	eglImageRGBAOut_.reset();
+	eglImageRGBAOut_.clear();
 	eglImagePingPong_[1].reset();
 	eglImagePingPong_[0].reset();
 	eglImageBayerIn_.reset();
diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.h b/src/libcamera/software_isp/software_isp_pipeline_gpu.h
index b32d4cad3..995e84295 100644
--- a/src/libcamera/software_isp/software_isp_pipeline_gpu.h
+++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.h
@@ -69,7 +69,7 @@ private:
 	/* Pointer to object representing input texture */
 	std::unique_ptr<eGLImage> eglImageBayerIn_;
 	std::unique_ptr<eGLImage> eglImagePingPong_[2];
-	std::unique_ptr<eGLImage> eglImageRGBAOut_;
+	std::unordered_map<FrameBuffer *, std::unique_ptr<eGLImage>> eglImageRGBAOut_;
 
 	std::unique_ptr<SwStatsCpu> stats_;
 	eGL egl_;
