diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp
index 458b65854..18a8ae17a 100644
--- a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp
+++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp
@@ -335,6 +335,10 @@ int SoftwareIspPipelineGpu::start()
 	/* Raw bayer input as texture */
 	eglImageBayerIn_ = std::make_unique<eGLImage>(gpuIspShaderPassDemosiac_.glFormat_, inputConfig_.stride / gpuIspShaderPassDemosiac_.getBytesPerPixel(), height_, inputConfig_.stride, GL_TEXTURE0, 0);
 
+	/* Intermediary ping/pong textures */
+	eglImagePingPong_[0] = std::make_unique<eGLImage>(gpuIspShaderPassDemosiac_.glFormat_, outputSize_.width, outputSize_.height, outputConfig_.stride, GL_TEXTURE1, 1);
+	eglImagePingPong_[1] = std::make_unique<eGLImage>(gpuIspShaderPassDemosiac_.glFormat_, outputSize_.width, outputSize_.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);
 
@@ -344,6 +348,8 @@ int SoftwareIspPipelineGpu::start()
 void SoftwareIspPipelineGpu::stop()
 {
 	eglImageRGBAOut_.reset();
+	eglImagePingPong_[1].reset();
+	eglImagePingPong_[0].reset();
 	eglImageBayerIn_.reset();
 
 	gpuIspShaderPassDemosiac_.stop();
diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.h b/src/libcamera/software_isp/software_isp_pipeline_gpu.h
index 1b77bc71d..fcd622492 100644
--- a/src/libcamera/software_isp/software_isp_pipeline_gpu.h
+++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.h
@@ -65,6 +65,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::unique_ptr<SwStatsCpu> stats_;
