Пример #1
0
BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage usage)
{
    TypedBufferStorage11 *directBuffer = NULL;
    auto directBufferIt = mTypedBuffers.find(usage);
    if (directBufferIt != mTypedBuffers.end())
    {
        directBuffer = directBufferIt->second;
    }

    if (!directBuffer)
    {
        if (usage == BUFFER_USAGE_PIXEL_PACK)
        {
            directBuffer = new PackStorage11(mRenderer);
        }
        else
        {
            // buffer is not allocated, create it
            directBuffer = new NativeBuffer11(mRenderer, usage);
        }

        mTypedBuffers.insert(std::make_pair(usage, directBuffer));
    }

    // resize buffer
    if (directBuffer->getSize() < mSize)
    {
        if (!directBuffer->resize(mSize, true))
        {
            // Out of memory error
            return NULL;
        }
    }

    TypedBufferStorage11 *latestBuffer = getLatestStorage();
    if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
    {
        // if copying from a pack buffer to a non-staging native buffer, we must first
        // copy through the staging buffer, because other native buffers can't be mapped
        if (latestBuffer->getUsage() == BUFFER_USAGE_PIXEL_PACK && !directBuffer->isMappable())
        {
            NativeBuffer11 *stagingBuffer = getStagingBuffer();

            stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
            directBuffer->setDataRevision(latestBuffer->getDataRevision());

            latestBuffer = stagingBuffer;
        }

        // if copyFromStorage returns true, the D3D buffer has been recreated
        // and we should update our serial
        if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
        {
            updateSerial();
        }
        directBuffer->setDataRevision(latestBuffer->getDataRevision());
    }

    return directBuffer;
}
Пример #2
0
gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
{
    SafeRelease(mVertexBuffer);

    updateSerial();

    if (size > 0)
    {
        DWORD flags = D3DUSAGE_WRITEONLY;
        if (dynamicUsage)
        {
            flags |= D3DUSAGE_DYNAMIC;
        }

        HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer);

        if (FAILED(result))
        {
            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
        }
    }

    mBufferSize = size;
    mDynamicUsage = dynamicUsage;
    return gl::Error(GL_NO_ERROR);
}
Пример #3
0
gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
{
    SafeRelease(mBuffer);

    updateSerial();

    if (size > 0)
    {
        ID3D11Device* dxDevice = mRenderer->getDevice();

        D3D11_BUFFER_DESC bufferDesc;
        bufferDesc.ByteWidth = size;
        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
        bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
        bufferDesc.MiscFlags = 0;
        bufferDesc.StructureByteStride = 0;

        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
        if (FAILED(result))
        {
            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size);
        }
    }

    mBufferSize = size;
    mDynamicUsage = dynamicUsage;

    return gl::Error(GL_NO_ERROR);
}
Пример #4
0
bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
{
    SafeRelease(mBuffer);

    updateSerial();

    if (bufferSize > 0)
    {
        ID3D11Device* dxDevice = mRenderer->getDevice();

        D3D11_BUFFER_DESC bufferDesc;
        bufferDesc.ByteWidth = bufferSize;
        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
        bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
        bufferDesc.MiscFlags = 0;
        bufferDesc.StructureByteStride = 0;

        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
        if (FAILED(result))
        {
            return false;
        }
    }

    mBufferSize = bufferSize;
    mIndexType = indexType;
    mDynamicUsage = dynamic;

    return true;
}
Пример #5
0
bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
{
    if (mBuffer)
    {
        mBuffer->Release();
        mBuffer = NULL;
    }

    updateSerial();

    if (size > 0)
    {
        ID3D11Device* dxDevice = mRenderer->getDevice();

        D3D11_BUFFER_DESC bufferDesc;
        bufferDesc.ByteWidth = size;
        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
        bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
        bufferDesc.MiscFlags = 0;
        bufferDesc.StructureByteStride = 0;

        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
        if (FAILED(result))
        {
            return false;
        }
    }

    mBufferSize = size;
    mDynamicUsage = dynamicUsage;
    return true;
}
Пример #6
0
void QVGPixmapData::resize(int wid, int ht)
{
    if (w == wid && h == ht) {
        updateSerial();
        return;
    }

    w = wid;
    h = ht;
    d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
    is_null = (w <= 0 || h <= 0);
    source = QVolatileImage();
    recreate = true;

    updateSerial();
}
Пример #7
0
/// -------------------- Update -------------------- ///
void MotionerIMU::update()
{
    updateSerial();
    
    updateValues();
    
    const bool ret = updateVelocity();
    
  //  updateCAN();
}
Пример #8
0
BufferD3D::BufferD3D(BufferFactoryD3D *factory)
    : BufferImpl(),
      mFactory(factory),
      mStaticVertexBuffer(nullptr),
      mStaticIndexBuffer(nullptr),
      mUnmodifiedDataUse(0),
      mUsage(D3D_BUFFER_USAGE_STATIC)
{
    updateSerial();
}
bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
{
    if (mIndexBuffer)
    {
        mIndexBuffer->Release();
        mIndexBuffer = NULL;
    }

    updateSerial();

    if (bufferSize > 0)
    {
        D3DFORMAT format;
        if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
        {
            format = D3DFMT_INDEX16;
        }
        else if (indexType == GL_UNSIGNED_INT)
        {
            if (mRenderer->get32BitIndexSupport())
            {
                format = D3DFMT_INDEX32;
            }
            else
            {
                ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices.");
                return false;
            }
        }
        else
        {
            ERR("Invalid index type %u.", indexType);
            return false;
        }

        DWORD usageFlags = D3DUSAGE_WRITEONLY;
        if (dynamic)
        {
            usageFlags |= D3DUSAGE_DYNAMIC;
        }

        HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
        if (FAILED(result))
        {
            ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result);
            return false;
        }
    }

    mBufferSize = bufferSize;
    mIndexType = indexType;
    mDynamic = dynamic;

    return true;
}
Пример #10
0
BufferD3D::BufferD3D(BufferFactoryD3D *factory)
    : BufferImpl(),
      mFactory(factory),
      mStaticIndexBuffer(nullptr),
      mStaticBufferCacheTotalSize(0),
      mStaticVertexBufferOutOfDate(false),
      mUnmodifiedDataUse(0),
      mUsage(D3DBufferUsage::STATIC)
{
    updateSerial();
}
Пример #11
0
void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
{
    if (type == QPixmapData::SgImage && pixmap) {
#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
        RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
        destroyImages();
        prevSize = QSize();

        vgImage = sgImageToVGImage(context, *sgImage);
        if (vgImage != VG_INVALID_HANDLE) {
            w = vgGetParameteri(vgImage, VG_IMAGE_WIDTH);
            h = vgGetParameteri(vgImage, VG_IMAGE_HEIGHT);
            d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
        }

        is_null = (w <= 0 || h <= 0);
        source = QVolatileImage(); // readback will be done later, only when needed
        recreate = false;
        prevSize = QSize(w, h);
        updateSerial();
#endif
    } else if (type == QPixmapData::FbsBitmap && pixmap) {
        CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
        QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
        resize(size.width(), size.height());
        source = QVolatileImage(bitmap); // duplicates only, if possible
        if (source.isNull())
            return;
        if (!conversionLessFormat(source.format())) {
            // Here we may need to copy if the formats do not match.
            // (e.g. for display modes other than EColor16MAP and EColor16MU)
            source.beginDataAccess();
            QImage::Format format = idealFormat(&source.imageRef(), Qt::AutoColor);
            source.endDataAccess(true);
            source.ensureFormat(format);
        }
        recreate = true;
    } else if (type == QPixmapData::VolatileImage && pixmap) {
        QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
        resize(img->width(), img->height());
        source = *img;
        recreate = true;
    } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
        destroyImages();
        nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
        // Cannot defer the retrieval, we need at least the size right away.
        createFromNativeImageHandleProvider();
    }
}
Пример #12
0
QVGPixmapData::QVGPixmapData(PixelType type)
    : QPixmapData(type, OpenVGClass)
{
    Q_ASSERT(type == QPixmapData::PixmapType);
    vgImage = VG_INVALID_HANDLE;
    vgImageOpacity = VG_INVALID_HANDLE;
    cachedOpacity = 1.0f;
    recreate = true;
    inImagePool = false;
    inLRU = false;
#if defined(Q_OS_SYMBIAN)
    nativeImageHandleProvider = 0;
    nativeImageHandle = 0;
#endif
#if !defined(QT_NO_EGL)
    context = 0;
    qt_vg_register_pixmap(this);
#endif
    updateSerial();
}
Пример #13
0
gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
{
    SafeRelease(mBuffer);

    updateSerial();

    if (bufferSize > 0)
    {
        ID3D11Device* dxDevice = mRenderer->getDevice();

        D3D11_BUFFER_DESC bufferDesc;
        bufferDesc.ByteWidth = bufferSize;
        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
        bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
        bufferDesc.MiscFlags = 0;
        bufferDesc.StructureByteStride = 0;

        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
        if (FAILED(result))
        {
            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
        }

        if (dynamic)
        {
            d3d11::SetDebugName(mBuffer, "IndexBuffer11 (dynamic)");
        }
        else
        {
            d3d11::SetDebugName(mBuffer, "IndexBuffer11 (static)");
        }
    }

    mBufferSize = bufferSize;
    mIndexType = indexType;
    mDynamicUsage = dynamic;

    return gl::Error(GL_NO_ERROR);
}
Пример #14
0
gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
{
    SafeRelease(mIndexBuffer);

    updateSerial();

    if (bufferSize > 0)
    {
        D3DFORMAT format = D3DFMT_UNKNOWN;
        if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
        {
            format = D3DFMT_INDEX16;
        }
        else if (indexType == GL_UNSIGNED_INT)
        {
            ASSERT(mRenderer->getRendererExtensions().elementIndexUint);
            format = D3DFMT_INDEX32;
        }
        else UNREACHABLE();

        DWORD usageFlags = D3DUSAGE_WRITEONLY;
        if (dynamic)
        {
            usageFlags |= D3DUSAGE_DYNAMIC;
        }

        HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
        if (FAILED(result))
        {
            return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
        }
    }

    mBufferSize = bufferSize;
    mIndexType = indexType;
    mDynamic = dynamic;

    return gl::Error(GL_NO_ERROR);
}
Пример #15
0
void Memory::updateIrqs(unsigned long cc) {
	updateSerial(cc);
	updateTimaIrq(cc);
	lcd_.update(cc);
}
Пример #16
0
unsigned long Memory::event(unsigned long cc) {
	if (lastOamDmaUpdate_ != disabled_time)
		updateOamDma(cc);

	switch (intreq_.minEventId()) {
	case intevent_unhalt:
		intreq_.unhalt();
		intreq_.setEventTime<intevent_unhalt>(disabled_time);
		break;
	case intevent_end:
		intreq_.setEventTime<intevent_end>(disabled_time - 1);

		while (cc >= intreq_.minEventTime()
				&& intreq_.eventTime(intevent_end) != disabled_time) {
			cc = event(cc);
		}

		intreq_.setEventTime<intevent_end>(disabled_time);

		break;
	case intevent_blit:
		{
			bool const lcden = ioamhram_[0x140] & lcdc_en;
			unsigned long blitTime = intreq_.eventTime(intevent_blit);

			if (lcden | blanklcd_) {
				lcd_.updateScreen(blanklcd_, cc);
				intreq_.setEventTime<intevent_blit>(disabled_time);
				intreq_.setEventTime<intevent_end>(disabled_time);

				while (cc >= intreq_.minEventTime())
					cc = event(cc);
			} else
				blitTime += 70224 << isDoubleSpeed();

			blanklcd_ = lcden ^ 1;
			intreq_.setEventTime<intevent_blit>(blitTime);
		}
		break;
	case intevent_serial:
		updateSerial(cc);
		break;
	case intevent_oam:
		intreq_.setEventTime<intevent_oam>(lastOamDmaUpdate_ == disabled_time
			? static_cast<unsigned long>(disabled_time)
			: intreq_.eventTime(intevent_oam) + 0xA0 * 4);
		break;
	case intevent_dma:
		{
			bool const doubleSpeed = isDoubleSpeed();
			unsigned dmaSrc = dmaSource_;
			unsigned dmaDest = dmaDestination_;
			unsigned dmaLength = ((ioamhram_[0x155] & 0x7F) + 0x1) * 0x10;
			unsigned length = hdmaReqFlagged(intreq_) ? 0x10 : dmaLength;

			ackDmaReq(intreq_);

			if ((static_cast<unsigned long>(dmaDest) + length) & 0x10000) {
				length = 0x10000 - dmaDest;
				ioamhram_[0x155] |= 0x80;
			}

			dmaLength -= length;

			if (!(ioamhram_[0x140] & lcdc_en))
				dmaLength = 0;

			{
				unsigned long lOamDmaUpdate = lastOamDmaUpdate_;
				lastOamDmaUpdate_ = disabled_time;

				while (length--) {
					unsigned const src = dmaSrc++ & 0xFFFF;
					unsigned const data = (src & 0xE000) == 0x8000 || src > 0xFDFF
					                    ? 0xFF
					                    : read(src, cc);

					cc += 2 << doubleSpeed;

					if (cc - 3 > lOamDmaUpdate) {
						oamDmaPos_ = (oamDmaPos_ + 1) & 0xFF;
						lOamDmaUpdate += 4;

						if (oamDmaPos_ < 0xA0) {
							if (oamDmaPos_ == 0)
								startOamDma(lOamDmaUpdate - 1);

							ioamhram_[src & 0xFF] = data;
						} else if (oamDmaPos_ == 0xA0) {
							endOamDma(lOamDmaUpdate - 1);
							lOamDmaUpdate = disabled_time;
						}
					}

					nontrivial_write(0x8000 | (dmaDest++ & 0x1FFF), data, cc);
				}

				lastOamDmaUpdate_ = lOamDmaUpdate;
			}

			cc += 4;

			dmaSource_ = dmaSrc;
			dmaDestination_ = dmaDest;
			ioamhram_[0x155] = ((dmaLength / 0x10 - 0x1) & 0xFF) | (ioamhram_[0x155] & 0x80);

			if ((ioamhram_[0x155] & 0x80) && lcd_.hdmaIsEnabled()) {
				if (lastOamDmaUpdate_ != disabled_time)
					updateOamDma(cc);

				lcd_.disableHdma(cc);
			}
		}

		break;
	case intevent_tima:
		tima_.doIrqEvent(TimaInterruptRequester(intreq_));
		break;
	case intevent_video:
		lcd_.update(cc);
		break;
	case intevent_interrupts:
		if (halted()) {
			if (isCgb())
				cc += 4;

			intreq_.unhalt();
			intreq_.setEventTime<intevent_unhalt>(disabled_time);
		}

		if (ime()) {
			unsigned const pendingIrqs = intreq_.pendingIrqs();
			unsigned const n = pendingIrqs & -pendingIrqs;
			unsigned address;
			if (n <= 4) {
				static unsigned char const lut[] = { 0x40, 0x48, 0x48, 0x50 };
				address = lut[n-1];
			} else
				address = 0x50 + n;

			intreq_.ackIrq(n);
			cc = interrupter_.interrupt(address, cc, *this);
		}

		break;
	}

	return cc;
}
Пример #17
0
VertexBuffer::VertexBuffer()
{
    updateSerial();
}
Пример #18
0
Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
{
    BufferStorage *newStorage = NULL;
    auto directBufferIt = mBufferStorages.find(usage);
    if (directBufferIt != mBufferStorages.end())
    {
        newStorage = directBufferIt->second;
    }

    if (!newStorage)
    {
        if (usage == BUFFER_USAGE_PIXEL_PACK)
        {
            newStorage = new PackStorage(mRenderer);
        }
        else if (usage == BUFFER_USAGE_SYSTEM_MEMORY)
        {
            newStorage = new SystemMemoryStorage(mRenderer);
            mHasSystemMemoryStorage = true;
        }
        else
        {
            // buffer is not allocated, create it
            newStorage = new NativeStorage(mRenderer, usage);
        }

        mBufferStorages.insert(std::make_pair(usage, newStorage));
    }

    // resize buffer
    if (newStorage->getSize() < mSize)
    {
        if (newStorage->resize(mSize, true).isError())
        {
            // Out of memory error
            return NULL;
        }
    }

    BufferStorage *latestBuffer = getLatestBufferStorage();
    if (latestBuffer && latestBuffer->getDataRevision() > newStorage->getDataRevision())
    {
        // Copy through a staging buffer if we're copying from or to a non-staging, mappable
        // buffer storage. This is because we can't map a GPU buffer, and copy CPU
        // data directly. If we're already using a staging buffer we're fine.
        if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING &&
            newStorage->getUsage() != BUFFER_USAGE_STAGING &&
            (!latestBuffer->isMappable() || !newStorage->isMappable()))
        {
            NativeStorage *stagingBuffer = getStagingStorage();

            stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
            stagingBuffer->setDataRevision(latestBuffer->getDataRevision());

            latestBuffer = stagingBuffer;
        }

        // if copyFromStorage returns true, the D3D buffer has been recreated
        // and we should update our serial
        if (newStorage->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
        {
            updateSerial();
        }
        newStorage->setDataRevision(latestBuffer->getDataRevision());
    }

    return newStorage;
}
Пример #19
0
void Memory::updateIrqs(const unsigned long cc) {
	updateSerial(cc);
	updateTimaIrq(cc);
	display.update(cc);
}
Пример #20
0
void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset, GLenum bindingPoint)
{
    ID3D11Device *device = mRenderer->getDevice();
    ID3D11DeviceContext *context = mRenderer->getDeviceContext();
    HRESULT result;

    unsigned int requiredBufferSize = size + offset;
    unsigned int requiredStagingSize = size;
    bool directInitialization = offset == 0 && (!mBuffer || mBufferSize < size + offset);

    if (!directInitialization)
    {
        if (!mStagingBuffer || mStagingBufferSize < requiredStagingSize)
        {
            if (mStagingBuffer)
            {
                mStagingBuffer->Release();
                mStagingBuffer = NULL;
                mStagingBufferSize = 0;
            }

            D3D11_BUFFER_DESC bufferDesc;
            bufferDesc.ByteWidth = size;
            bufferDesc.Usage = D3D11_USAGE_STAGING;
            bufferDesc.BindFlags = 0;
            bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
            bufferDesc.MiscFlags = 0;
            bufferDesc.StructureByteStride = 0;

            if (data)
            {
                D3D11_SUBRESOURCE_DATA initialData;
                initialData.pSysMem = data;
                initialData.SysMemPitch = size;
                initialData.SysMemSlicePitch = 0;

                result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer);
            }
            else
            {
                result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer);
            }

            if (FAILED(result))
            {
                return gl::error(GL_OUT_OF_MEMORY);
            }

            mStagingBufferSize = size;
        }
        else if (data)
        {
            D3D11_MAPPED_SUBRESOURCE mappedResource;
            result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
            if (FAILED(result))
            {
                return gl::error(GL_OUT_OF_MEMORY);
            }

            memcpy(mappedResource.pData, data, size);

            context->Unmap(mStagingBuffer, 0);
        }
    }

    if (!mBuffer || mBufferSize < size + offset)
    {
        D3D11_BUFFER_DESC bufferDesc;
        bufferDesc.ByteWidth = requiredBufferSize;
        bufferDesc.Usage = D3D11_USAGE_DEFAULT;
        if (mRenderer->getMajorShaderModel() > 2)
            bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
        else
        {
            if (bindingPoint == GL_ARRAY_BUFFER)
                bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
            else
                bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
        }
        bufferDesc.CPUAccessFlags = 0;
        bufferDesc.MiscFlags = 0;
        bufferDesc.StructureByteStride = 0;

        if (directInitialization)
        {
            // Since the data will fill the entire buffer (being larger than the initial size and having
            // no offset), the buffer can be initialized with the data so no staging buffer is required

            // No longer need the old buffer
            if (mBuffer)
            {
                mBuffer->Release();
                mBuffer = NULL;
                mBufferSize = 0;
            }

            if (data)
            {
                D3D11_SUBRESOURCE_DATA initialData;
                initialData.pSysMem = data;
                initialData.SysMemPitch = size;
                initialData.SysMemSlicePitch = 0;

                result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer);
            }
            else
            {
                result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
            }

            if (FAILED(result))
            {
                return gl::error(GL_OUT_OF_MEMORY);
            }
        }
        else if (mBuffer && offset > 0)
        {
            // If offset is greater than zero and the buffer is non-null, need to preserve the data from
            // the old buffer up to offset
            ID3D11Buffer *newBuffer = NULL;

            result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
            if (FAILED(result))
            {
                return gl::error(GL_OUT_OF_MEMORY);
            }

            D3D11_BOX srcBox;
            srcBox.left = 0;
            srcBox.right = std::min(offset, mBufferSize);
            srcBox.top = 0;
            srcBox.bottom = 1;
            srcBox.front = 0;
            srcBox.back = 1;

            context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox);

            mBuffer->Release();
            mBuffer = newBuffer;
        }
        else
        {
            // Simple case, nothing needs to be copied from the old buffer to the new one, just create
            // a new buffer

            // No longer need the old buffer
            if (mBuffer)
            {
                mBuffer->Release();
                mBuffer = NULL;
                mBufferSize = 0;
            }

            // Create a new buffer for data storage
            result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
            if (FAILED(result))
            {
                return gl::error(GL_OUT_OF_MEMORY);
            }
        }

        updateSerial();
        mBufferSize = bufferDesc.ByteWidth;
    }

    if (!directInitialization)
    {
        ASSERT(mStagingBuffer && mStagingBufferSize >= requiredStagingSize);

        // Data is already put into the staging buffer, copy it over to the data buffer
        D3D11_BOX srcBox;
        srcBox.left = 0;
        srcBox.right = size;
        srcBox.top = 0;
        srcBox.bottom = 1;
        srcBox.front = 0;
        srcBox.back = 1;

        context->CopySubresourceRegion(mBuffer, 0, offset, 0, 0, mStagingBuffer, 0, &srcBox);
    }

    mSize = std::max(mSize, offset + size);

    mWriteUsageCount = 0;

    mResolvedDataValid = false;
}
Пример #21
0
IndexBuffer::IndexBuffer()
{
    updateSerial();
}
Пример #22
0
unsigned long Memory::event(unsigned long cycleCounter) {
	if (lastOamDmaUpdate != DISABLED_TIME)
		updateOamDma(cycleCounter);

	switch (intreq.minEventId()) {
	case UNHALT:
		nontrivial_ff_write(0xFF04, 0, cycleCounter);
		PC = (PC + 1) & 0xFFFF;
		cycleCounter += 4;
		intreq.unhalt();
		intreq.setEventTime<UNHALT>(DISABLED_TIME);
		break;
	case END:
		intreq.setEventTime<END>(DISABLED_TIME - 1);

		while (cycleCounter >= intreq.minEventTime() && intreq.eventTime(END) != DISABLED_TIME)
			cycleCounter = event(cycleCounter);
		
		intreq.setEventTime<END>(DISABLED_TIME);

		break;
	case BLIT:
		{
			const bool lcden = ioamhram[0x140] >> 7 & 1;
			unsigned long blitTime = intreq.eventTime(BLIT);
			
			if (lcden | blanklcd) {
				display.updateScreen(blanklcd, cycleCounter);
				intreq.setEventTime<BLIT>(DISABLED_TIME);
				intreq.setEventTime<END>(DISABLED_TIME);
				
				while (cycleCounter >= intreq.minEventTime())
					cycleCounter = event(cycleCounter);
			} else
				blitTime += 70224 << isDoubleSpeed();
			
			blanklcd = lcden ^ 1;
			intreq.setEventTime<BLIT>(blitTime);
		}
		break;
	case SERIAL:
		updateSerial(cycleCounter);
		break;
	case OAM:
		intreq.setEventTime<OAM>(lastOamDmaUpdate == DISABLED_TIME ?
				static_cast<unsigned long>(DISABLED_TIME) : intreq.eventTime(OAM) + 0xA0 * 4);
		break;
	case DMA:
		{
			const bool doubleSpeed = isDoubleSpeed();
			unsigned dmaSrc = dmaSource;
			unsigned dmaDest = dmaDestination;
			unsigned dmaLength = ((ioamhram[0x155] & 0x7F) + 0x1) * 0x10;
			unsigned length = hdmaReqFlagged(intreq) ? 0x10 : dmaLength;
			
			ackDmaReq(&intreq);

			if ((static_cast<unsigned long>(dmaDest) + length) & 0x10000) {
				length = 0x10000 - dmaDest;
				ioamhram[0x155] |= 0x80;
			}

			dmaLength -= length;

			if (!(ioamhram[0x140] & 0x80))
				dmaLength = 0;

			{
				unsigned long lOamDmaUpdate = lastOamDmaUpdate;
				lastOamDmaUpdate = DISABLED_TIME;

				while (length--) {
					const unsigned src = dmaSrc++ & 0xFFFF;
					const unsigned data = ((src & 0xE000) == 0x8000 || src > 0xFDFF) ? 0xFF : read(src, cycleCounter);

					cycleCounter += 2 << doubleSpeed;

					if (cycleCounter - 3 > lOamDmaUpdate) {
						oamDmaPos = (oamDmaPos + 1) & 0xFF;
						lOamDmaUpdate += 4;

						if (oamDmaPos < 0xA0) {
							if (oamDmaPos == 0)
								startOamDma(lOamDmaUpdate - 1);

							ioamhram[src & 0xFF] = data;
						} else if (oamDmaPos == 0xA0) {
							endOamDma(lOamDmaUpdate - 1);
							lOamDmaUpdate = DISABLED_TIME;
						}
					}

					nontrivial_write(0x8000 | (dmaDest++ & 0x1FFF), data, cycleCounter);
				}

				lastOamDmaUpdate = lOamDmaUpdate;
			}

			cycleCounter += 4;

			dmaSource = dmaSrc;
			dmaDestination = dmaDest;
			ioamhram[0x155] = ((dmaLength / 0x10 - 0x1) & 0xFF) | (ioamhram[0x155] & 0x80);

			if ((ioamhram[0x155] & 0x80) && display.hdmaIsEnabled()) {
				if (lastOamDmaUpdate != DISABLED_TIME)
					updateOamDma(cycleCounter);
				
				display.disableHdma(cycleCounter);
			}
		}

		break;
	case TIMA:
		tima.doIrqEvent(TimaInterruptRequester(intreq));
		break;
	case VIDEO:
		display.update(cycleCounter);
		break;
	case INTERRUPTS:
		if (stopped) {
			intreq.setEventTime<INTERRUPTS>(DISABLED_TIME);
			break;
		}
		if (halted()) {
			if (gbIsCgb_ || (!gbIsCgb_ && cycleCounter <= halttime + 4))
				cycleCounter += 4;
			
			intreq.unhalt();
			intreq.setEventTime<UNHALT>(DISABLED_TIME);
		}
		
		if (ime()) {
			unsigned address;

			cycleCounter += 12;
			display.update(cycleCounter);
			SP = (SP - 2) & 0xFFFF;
			write(SP + 1, PC >> 8, cycleCounter);
			unsigned ie = intreq.iereg();

			cycleCounter += 4;
			display.update(cycleCounter);
			write(SP, PC & 0xFF, cycleCounter);
			const unsigned pendingIrqs = ie & intreq.ifreg();

			cycleCounter += 4;
			display.update(cycleCounter);
			const unsigned n = pendingIrqs & -pendingIrqs;
			
			if (n == 0) {
				address = 0;
			}
			else if (n < 8) {
				static const unsigned char lut[] = { 0x40, 0x48, 0x48, 0x50 };
				address = lut[n-1];
			} else
				address = 0x50 + n;
			
			intreq.ackIrq(n);
			PC = address;
		}
		
		break;
	}

	return cycleCounter;
}