//--------------------------------------------------------------------- D3D11HardwareBuffer::D3D11HardwareBuffer( BufferType btype, size_t sizeBytes, HardwareBuffer::Usage usage, D3D11Device & device, bool useSystemMemory, bool useShadowBuffer) : HardwareBuffer(usage, useSystemMemory, false /* TODO: useShadowBuffer*/), mlpD3DBuffer(0), mpTempStagingBuffer(0), mUseTempStagingBuffer(false), mBufferType(btype), mDevice(device) { mSizeInBytes = sizeBytes; mDesc.ByteWidth = static_cast<UINT>(sizeBytes); mDesc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); if (useSystemMemory) { mDesc.Usage = D3D11_USAGE_STAGING; //A D3D11_USAGE_STAGING Resource cannot be bound to any parts of the graphics pipeline, so therefore cannot have any BindFlags bits set. mDesc.BindFlags = 0; mDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ ;// A D3D11_USAGE_STAGING Resource must have at least one CPUAccessFlag bit set. } else { mDesc.Usage = D3D11Mappings::_getUsage(mUsage); mDesc.BindFlags = btype == VERTEX_BUFFER ? D3D11_BIND_VERTEX_BUFFER : D3D11_BIND_INDEX_BUFFER; } mDesc.MiscFlags = 0; if (!useSystemMemory && (usage | HardwareBuffer::HBU_DYNAMIC)) { // We want to be able to map this buffer mDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; mDesc.Usage = D3D11_USAGE_DYNAMIC; } // Note that in D3D11 you can only directly lock (map) a dynamic resource // directly for writing. You can only map for read / write staging resources, // which themselves cannot be used for input / output to the GPU. Thus // for any locks except write locks on dynamic resources, we have to use // temporary staging resources instead and use async copies. // We use the 'useSystemMemory' option to indicate a staging resource // TODO: we can explicitly initialise the buffer contents here if we like // not doing this since OGRE doesn't support this model yet HRESULT hr = device->CreateBuffer( &mDesc, 0, &mlpD3DBuffer ); if (FAILED(hr) || mDevice.isError()) { String msg = device.getErrorDescription(hr); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create D3D11 buffer: " + msg, "D3D11HardwareBuffer::D3D11HardwareBuffer"); } }
void D3D11GpuComputeProgram::loadFromMicrocode(D3D11Device& device, ID3D10Blob* microcode) { HRESULT hr = device.getD3D11Device()->CreateComputeShader( static_cast<DWORD*>(microcode->GetBufferPointer()), microcode->GetBufferSize(), device.getClassLinkage(), &mComputeShader); if (FAILED(hr) || device.hasError()) { String errorDescription = device.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "Cannot create D3D11 compute shader from microcode.\nError Description:" + errorDescription); } }
D3D11HardwareBuffer::D3D11HardwareBuffer(BufferType btype, GpuBufferUsage usage, UINT32 elementCount, UINT32 elementSize, D3D11Device& device, bool useSystemMem, bool streamOut, bool randomGpuWrite, bool useCounter) : HardwareBuffer(usage, useSystemMem), mD3DBuffer(nullptr), mpTempStagingBuffer(nullptr), mUseTempStagingBuffer(false), mBufferType(btype), mDevice(device), mElementCount(elementCount), mElementSize(elementSize), mRandomGpuWrite(randomGpuWrite), mUseCounter(useCounter) { assert((!streamOut || btype == BT_VERTEX) && "Stream out flag is only supported on vertex buffers"); assert(!randomGpuWrite || (btype & BT_GROUP_GENERIC) != 0 && "randomGpuWrite flag can only be enabled with append/consume, indirect argument, structured or raw buffers"); assert(btype != BT_APPENDCONSUME || randomGpuWrite && "Append/Consume buffer must be created with randomGpuWrite enabled."); assert(!useCounter || btype == BT_STRUCTURED && "Counter can only be used with a structured buffer."); assert(!useCounter || randomGpuWrite && "Counter can only be used with buffers that have randomGpuWrite enabled."); assert(!randomGpuWrite || !useSystemMem && "randomGpuWrite and useSystemMem cannot be used together."); assert(!(useSystemMem && streamOut) && "useSystemMem and streamOut cannot be used together."); mSizeInBytes = elementCount * elementSize; mDesc.ByteWidth = mSizeInBytes; mDesc.MiscFlags = 0; mDesc.StructureByteStride = 0; if (useSystemMem) { mDesc.Usage = D3D11_USAGE_STAGING; mDesc.BindFlags = 0; mDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ ; } else if(randomGpuWrite) { mDesc.Usage = D3D11_USAGE_DEFAULT; mDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; mDesc.CPUAccessFlags = 0; } else { mDesc.Usage = D3D11Mappings::getUsage(mUsage); mDesc.CPUAccessFlags = D3D11Mappings::getAccessFlags(mUsage); switch(btype) { case BT_VERTEX: mDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; if (streamOut) mDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT; break; case BT_INDEX: mDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; break; case BT_CONSTANT: mDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; break; case BT_STRUCTURED: case BT_APPENDCONSUME: mDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; mDesc.StructureByteStride = elementSize; mDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; break; case BT_RAW: mDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; mDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; break; case BT_INDIRECTARGUMENT: mDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; mDesc.MiscFlags = D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS; break; } } HRESULT hr = device.getD3D11Device()->CreateBuffer( &mDesc, nullptr, &mD3DBuffer ); if (FAILED(hr) || mDevice.hasError()) { String msg = device.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "Cannot create D3D11 buffer: " + msg); } }