/*-------------------------------------------------------------------------
 * drawElements Quality Program Reference Renderer
 * -----------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Multisampled pixel buffer access
 *//*--------------------------------------------------------------------*/

#include "rrMultisamplePixelBufferAccess.hpp"
#include "tcuTextureUtil.hpp"

namespace rr
{

MultisamplePixelBufferAccess::MultisamplePixelBufferAccess (const tcu::PixelBufferAccess& rawAccess)
	: m_access(rawAccess)
{
}

MultisamplePixelBufferAccess::MultisamplePixelBufferAccess (void)
	: m_access(tcu::PixelBufferAccess(tcu::TextureFormat(), 0, 0, 0, 0, 0, DE_NULL))
{
}

const tcu::PixelBufferAccess MultisamplePixelBufferAccess::toSinglesampleAccess (void) const
{
	DE_ASSERT(getNumSamples() == 1);

	return tcu::PixelBufferAccess(m_access.getFormat(),
								  m_access.getHeight(),
								  m_access.getDepth(),
								  1,
								  m_access.getSlicePitch(),
								  m_access.getSlicePitch() * m_access.getDepth(),
								  m_access.getDataPtr());
}

MultisamplePixelBufferAccess MultisamplePixelBufferAccess::fromSinglesampleAccess (const tcu::PixelBufferAccess& original)
{
	return MultisamplePixelBufferAccess(
				tcu::PixelBufferAccess(
								original.getFormat(),
								1,
								original.getWidth(),
								original.getHeight(),
								original.getFormat().getPixelSize(),
								original.getRowPitch(),
								original.getDataPtr()));
}

MultisamplePixelBufferAccess MultisamplePixelBufferAccess::fromMultisampleAccess (const tcu::PixelBufferAccess& multisampledAccess)
{
	return MultisamplePixelBufferAccess(multisampledAccess);
}

MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (void)
	: m_access(tcu::ConstPixelBufferAccess(tcu::TextureFormat(), 0, 0, 0, 0, 0, DE_NULL))
{
}

MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (const tcu::ConstPixelBufferAccess& rawAccess)
	: m_access(rawAccess)
{
}

MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (const rr::MultisamplePixelBufferAccess& msAccess)
	: m_access(msAccess.raw())
{
}

const tcu::ConstPixelBufferAccess MultisampleConstPixelBufferAccess::toSinglesampleAccess (void) const
{
	DE_ASSERT(getNumSamples() == 1);

	return tcu::ConstPixelBufferAccess(m_access.getFormat(),
									   m_access.getHeight(),
									   m_access.getDepth(),
									   1,
									   m_access.getSlicePitch(),
									   m_access.getSlicePitch() * m_access.getDepth(),
									   m_access.getDataPtr());
}

MultisampleConstPixelBufferAccess MultisampleConstPixelBufferAccess::fromSinglesampleAccess (const tcu::ConstPixelBufferAccess& original)
{
	return MultisampleConstPixelBufferAccess(
				tcu::ConstPixelBufferAccess(
								original.getFormat(),
								1,
								original.getWidth(),
								original.getHeight(),
								original.getFormat().getPixelSize(),
								original.getRowPitch(),
								original.getDataPtr()));
}

MultisampleConstPixelBufferAccess MultisampleConstPixelBufferAccess::fromMultisampleAccess (const tcu::ConstPixelBufferAccess& multisampledAccess)
{
	return MultisampleConstPixelBufferAccess(multisampledAccess);
}

MultisamplePixelBufferAccess getSubregion (const MultisamplePixelBufferAccess& access, int x, int y, int width, int height)
{
	return MultisamplePixelBufferAccess::fromMultisampleAccess(tcu::getSubregion(access.raw(), 0, x, y, access.getNumSamples(), width, height));
}

MultisampleConstPixelBufferAccess getSubregion (const MultisampleConstPixelBufferAccess& access, int x, int y, int width, int height)
{
	return MultisampleConstPixelBufferAccess::fromMultisampleAccess(tcu::getSubregion(access.raw(), 0, x, y, access.getNumSamples(), width, height));
}

void resolveMultisampleColorBuffer (const tcu::PixelBufferAccess& dst, const MultisampleConstPixelBufferAccess& src)
{
	DE_ASSERT(dst.getWidth() == src.raw().getHeight());
	DE_ASSERT(dst.getHeight() == src.raw().getDepth());

	float numSamplesInv = 1.0f / (float)src.getNumSamples();

	for (int y = 0; y < dst.getHeight(); y++)
	{
		for (int x = 0; x < dst.getWidth(); x++)
		{
			tcu::Vec4 sum;
			for (int s = 0; s < src.raw().getWidth(); s++)
				sum += src.raw().getPixel(s, x, y);

			dst.setPixel(sum*numSamplesInv, x, y);
		}
	}
}

tcu::Vec4 resolveMultisamplePixel (const MultisampleConstPixelBufferAccess& access, int x, int y)
{
	tcu::Vec4 sum;
	for (int s = 0; s < access.getNumSamples(); s++)
		sum += access.raw().getPixel(s, x, y);

	return sum / (float)access.getNumSamples();
}

void clear (const MultisamplePixelBufferAccess& access, const tcu::Vec4& color)
{
	tcu::clear(access.raw(), color);
}

void clear (const MultisamplePixelBufferAccess& access, const tcu::IVec4& color)
{
	tcu::clear(access.raw(), color);
}

void clearDepth (const MultisamplePixelBufferAccess& access, float depth)
{
	tcu::clearDepth(access.raw(), depth);
}

void clearStencil (const MultisamplePixelBufferAccess& access, int stencil)
{
	tcu::clearStencil(access.raw(), stencil);
}

} // rr
