//Shutdown Buffers Function (Release Index and Vertex Buffer) void CModel::ShutdownBuffers() { ModelProperties* currentModel = GetModel(); //Get List of SubMeshs vector<CMesh::SubMesh*> subMeshList = currentModel->Mesh->GetSubMeshList(); //Iterate through SubMeshes for (int subMeshCount = 0; subMeshCount < currentModel->Mesh->GetSubMeshNum(); subMeshCount++) { CMesh::SubMesh* currentMesh = subMeshList[subMeshCount]; ID3D11Buffer* VertexBuffer = currentMesh->VertexBuffer; ID3D11Buffer* IndexBuffer = currentMesh->IndexBuffer; //Release Buffers if (IndexBuffer) { IndexBuffer->Release(); IndexBuffer = 0; } if (VertexBuffer) { VertexBuffer->Release(); VertexBuffer = 0; } } return; }
MF_API void MFVertex_UnlockIndexBuffer(MFIndexBuffer *pIndexBuffer) { MFDebug_Assert(pIndexBuffer, "NULL index buffer"); MFDebug_Assert(pIndexBuffer->bLocked, "Index buffer not locked!"); ID3D11Buffer *pIB = (ID3D11Buffer*)pIndexBuffer->pPlatformData; if(pIB) pIB->Release(); D3D11_BUFFER_DESC bd; MFZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_IMMUTABLE; bd.ByteWidth = sizeof(WORD) * pIndexBuffer->numIndices; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; D3D11_SUBRESOURCE_DATA initData; MFZeroMemory(&initData, sizeof(initData)); initData.pSysMem = pIndexBuffer->pLocked; HRESULT hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &pIB); MFDebug_Assert(SUCCEEDED(hr), "Couldn't create index buffer!"); if (FAILED(hr)) return; pIndexBuffer->pPlatformData = pIB; MFHeap_Free(pIndexBuffer->pLocked); pIndexBuffer->pLocked = NULL; pIndexBuffer->bLocked = false; }
// Create vertex/index buffers HRESULT CFW1GlyphVertexDrawer::createBuffers() { // Create vertex buffer D3D11_BUFFER_DESC vertexBufferDesc; ID3D11Buffer *pVertexBuffer; ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc)); vertexBufferDesc.ByteWidth = m_vertexBufferSize; vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; HRESULT hResult = m_pDevice->CreateBuffer(&vertexBufferDesc, NULL, &pVertexBuffer); if(FAILED(hResult)) { m_lastError = L"Failed to create vertex buffer"; } else { // Create index buffer D3D11_BUFFER_DESC indexBufferDesc; D3D11_SUBRESOURCE_DATA initData; ID3D11Buffer *pIndexBuffer; ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc)); indexBufferDesc.ByteWidth = sizeof(UINT16) * m_maxIndexCount; indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; UINT16 *indices = new UINT16[m_maxIndexCount]; for(UINT i=0; i < m_maxIndexCount/6; ++i) { indices[i*6] = static_cast<UINT16>(i*4); indices[i*6+1] = static_cast<UINT16>(i*4+1); indices[i*6+2] = static_cast<UINT16>(i*4+2); indices[i*6+3] = static_cast<UINT16>(i*4+1); indices[i*6+4] = static_cast<UINT16>(i*4+3); indices[i*6+5] = static_cast<UINT16>(i*4+2); } ZeroMemory(&initData, sizeof(initData)); initData.pSysMem = indices; hResult = m_pDevice->CreateBuffer(&indexBufferDesc, &initData, &pIndexBuffer); if(FAILED(hResult)) { m_lastError = L"Failed to create index buffer"; } else { // Success m_pVertexBuffer = pVertexBuffer; m_pIndexBuffer = pIndexBuffer; hResult = S_OK; } delete[] indices; if(FAILED(hResult)) pVertexBuffer->Release(); } return hResult; }
VertexBufferState MyD3DAssets::getActiveVertexBuffer() { VertexBufferState result; ID3D11Buffer *buffer; context->base->IAGetVertexBuffers(0, 1, &buffer, &result.stride, &result.offset); result.buffer = getBuffer(buffer); buffer->Release(); return result; }
IndexBufferState MyD3DAssets::getActiveIndexBuffer() { IndexBufferState result; ID3D11Buffer *buffer; context->base->IAGetIndexBuffer(&buffer, nullptr, &result.offset); result.buffer = getBuffer(buffer); buffer->Release(); return result; }
void services::Direct3D11Graphics::draw( const Vertex vertexes[], int vertexesSize, const wchar_t* texture, void* vertex, void* geometry, void* pixel ) { ID3D11Buffer* vertexBuffer; ID3D11ShaderResourceView* texResource; loadTexture( texture, texResource ); setShaderResource( (UINT16)pixel, 0, texResource ); D3D11_SAMPLER_DESC samplerDesc; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.MipLODBias = 0; samplerDesc.MaxAnisotropy = 0; samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; samplerDesc.BorderColor[0] = 0.f; samplerDesc.BorderColor[1] = 0.f; samplerDesc.BorderColor[2] = 0.f; samplerDesc.BorderColor[3] = 0.f; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; setSamplerState( (UINT16)pixel, 0, samplerDesc ); if ( (UINT16)vertex != _currentVertex && vertex >= 0 ) { _currentVertex = (UINT16)vertex; useShader<ID3D11VertexShader>( (UINT16)vertex ); } if ( (UINT16)geometry != _currentGeometry && geometry >= 0 ) { _currentGeometry = (UINT16)geometry; useShader<ID3D11GeometryShader>( (UINT16)geometry ); } useShader<ID3D11PixelShader>( (UINT16)pixel ); _createVertexBuffer( vertexes, vertexesSize, vertexBuffer ); _deviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // Draw _deviceContext->Draw( vertexesSize, 0 ); // Clean vertexBuffer->Release(); };
int Release() { if (VS) VS->Release(); if (PS) PS->Release(); if (inputLayout) inputLayout->Release(); if (vertexBuffer) vertexBuffer->Release(); return 0; }
const BufferCPU* MyD3DAssets::getPSConstantBuffer() { ID3D11Buffer *constantBuffer = nullptr; context->base->PSGetConstantBuffers(0, 1, &constantBuffer); if (constantBuffer == nullptr) { return nullptr; } if (buffers.count((UINT64)constantBuffer) == 0) { g_logger->logErrorFile << "Failed to find buffer: " << constantBuffer << endl; constantBuffer->Release(); return nullptr; } constantBuffer->Release(); return buffers.find((UINT64)constantBuffer)->second; }
DX11ScratchStructuredArray::DX11ScratchStructuredArray(const FromElementSize& arguments): element_count_(arguments.element_count), element_size_(arguments.element_size){ ID3D11Buffer* buffer; ID3D11Buffer* staging; ID3D11ShaderResourceView* srv; ID3D11UnorderedAccessView* uav; auto& device = *DX11Graphics::GetInstance().GetDevice(); THROW_ON_FAIL(::MakeStagingBuffer(device, static_cast<unsigned int>(element_count_), static_cast<unsigned int>(element_size_), true, &staging)); auto guard = make_scope_guard([&staging] { if (staging) { staging->Release(); } }); THROW_ON_FAIL(::MakeStructuredBuffer(device, static_cast<unsigned int>(element_count_), static_cast<unsigned int>(element_size_), false, &buffer, &srv, &uav)); shader_resource_view_ = COMMove(&srv); unordered_access_view_ = COMMove(&uav); buffer_ = COMMove(&buffer); readback_buffer_ = COMMove(&staging); raw_buffer_ = new char[element_size_ * element_count_]; guard.Dismiss(); }
unsigned int queryVSInvocations(ID3D11Device* device, ID3D11DeviceContext* context, const unsigned int* indices, size_t index_count) { if (index_count == 0) return 0; ID3D11Buffer* ib = 0; { D3D11_BUFFER_DESC bd = {}; bd.Usage = D3D11_USAGE_DYNAMIC; bd.ByteWidth = index_count * 4; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; device->CreateBuffer(&bd, 0, &ib); D3D11_MAPPED_SUBRESOURCE ms; context->Map(ib, 0, D3D11_MAP_WRITE_DISCARD, 0, &ms); memcpy(ms.pData, indices, index_count * 4); context->Unmap(ib, 0); } context->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->IASetIndexBuffer(ib, DXGI_FORMAT_R32_UINT, 0); D3D11_QUERY_DESC qdesc = {D3D11_QUERY_PIPELINE_STATISTICS}; ID3D11Query* query = 0; device->CreateQuery(&qdesc, &query); context->Begin(query); context->DrawIndexed(index_count, 0, 0); context->End(query); D3D11_QUERY_DATA_PIPELINE_STATISTICS stats = {}; while (S_FALSE == context->GetData(query, &stats, sizeof(stats), 0)) ; query->Release(); ib->Release(); assert(stats.IAVertices == index_count); return stats.VSInvocations; }
void TgcDX11Effect::dispose() { //Constant buffers for (unordered_map<string, ID3D11Buffer*>::iterator it = this->dxConstantBuffers.begin(); it != this->dxConstantBuffers.end(); ++it) { ID3D11Buffer* cBuffer = it->second; if(cBuffer) { cBuffer->Release(); cBuffer = 0; } } //Sampler states for (unordered_map<string, ID3D11SamplerState*>::iterator it = this->dxSampleStates.begin(); it != this->dxSampleStates.end(); ++it) { ID3D11SamplerState* sampler = it->second; if(sampler) { sampler->Release(); sampler = 0; } } //vertexShaderBuffer if(this->vertexShaderBuffer) { this->vertexShaderBuffer->Release(); this->vertexShaderBuffer = 0; } //vertexShader if(this->vertexShader) { this->vertexShader->Release(); this->vertexShader = 0; } //pixelShader if(this->pixelShader) { this->pixelShader->Release(); this->pixelShader = 0; } }
void services::Direct3D11Graphics::createConstantBuffer( UINT16 shader, UINT16 slot, int size ) { D3D11_BUFFER_DESC bufferDesc; HRESULT hr; ID3D11Buffer* buffer; pair<map<UINT16, ID3D11Buffer*>::const_iterator, bool> ret; map<UINT16, map<UINT16, ID3D11Buffer*>>::iterator constBuffer = _constantBuffers.find( shader ); if ( constBuffer == _constantBuffers.end() ) { throw; } bufferDesc.ByteWidth = size; bufferDesc.Usage = D3D11_USAGE_DEFAULT; bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bufferDesc.CPUAccessFlags = 0; bufferDesc.MiscFlags = 0; bufferDesc.StructureByteStride = 0; hr = _device->CreateBuffer( &bufferDesc, 0, &buffer ); if ( FAILED(hr) ) { throw "Erreur buffer matrice"; } ret = constBuffer->second.insert( pair<UINT16, ID3D11Buffer*>( slot, buffer ) ); if ( !ret.second ) { buffer->Release(); throw; } };
void DebugDraw::DrawAll(bool changesTyplogyBack) { if (numVerts > 0) { //Ge the old typology so we can set it back. D3D11_PRIMITIVE_TOPOLOGY oldTypology; deviceContext->IAGetPrimitiveTopology(&oldTypology); D3D11_BUFFER_DESC vbd; vbd.Usage = D3D11_USAGE_DYNAMIC; vbd.ByteWidth = sizeof(DebugVertex) * numVerts; vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; vbd.MiscFlags = 0; vbd.StructureByteStride = 0; D3D11_SUBRESOURCE_DATA initialVertexData; initialVertexData.pSysMem = vertices; ID3D11Buffer* vertexBuffer; device->CreateBuffer(&vbd, &initialVertexData, &vertexBuffer); UINT stride = sizeof(DebugVertex); UINT offset = 0; deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); vertexShader->SetMatrix4x4(0, DirectX::XMFLOAT4X4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)); vertexShader->SetMatrix4x4(1, camera->GetViewMatrix()); vertexShader->SetMatrix4x4(2, camera->GetProjectionMatrix()); vertexShader->SetShader(true); pixelShader->SetShader(true); deviceContext->Draw(numVerts, 0); if (changesTyplogyBack) { deviceContext->IASetPrimitiveTopology(oldTypology); } vertexBuffer->Release(); numVerts = 0; } }
MF_API void MFVertex_UnlockVertexBuffer(MFVertexBuffer *pVertexBuffer) { MFDebug_Assert(pVertexBuffer, "Null vertex buffer"); ID3D11Buffer *pVB = (ID3D11Buffer*)pVertexBuffer->pPlatformData; if(pVertexBuffer->bufferType == MFVBType_Dynamic) { g_pImmediateContext->Unmap(pVB, 0); } else { if(pVB) pVB->Release(); D3D11_BUFFER_DESC bd; MFZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_IMMUTABLE; bd.ByteWidth = pVertexBuffer->pVertexDeclatation->pElementData[0].stride * pVertexBuffer->numVerts; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA initData; MFZeroMemory(&initData, sizeof(initData)); initData.pSysMem = pVertexBuffer->pLocked; HRESULT hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &pVB); MFDebug_Assert(SUCCEEDED(hr), "Couldn't create vertex buffer!"); if(FAILED(hr)) { pVertexBuffer->pPlatformData = NULL; return; } pVertexBuffer->pPlatformData = pVB; MFHeap_Free(pVertexBuffer->pLocked); } pVertexBuffer->pLocked = NULL; pVertexBuffer->bLocked = false; }
static ID3D11Buffer * genTextureBuffer(ID3D11DeviceContext *deviceContext, int size, void const * data) { D3D11_BUFFER_DESC hBufferDesc; hBufferDesc.ByteWidth = size; hBufferDesc.Usage = D3D11_USAGE_DYNAMIC; hBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_SHADER_RESOURCE; hBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; hBufferDesc.MiscFlags = 0; hBufferDesc.StructureByteStride = sizeof(float); HRESULT hr; ID3D11Buffer *buffer; ID3D11Device *device; deviceContext->GetDevice(&device); hr = device->CreateBuffer(&hBufferDesc, NULL, &buffer); if (FAILED(hr)) { Far::Error(Far::FAR_RUNTIME_ERROR, "Fail in CreateBuffer\n"); return 0; } D3D11_MAPPED_SUBRESOURCE resource; hr = deviceContext->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); if (FAILED(hr)) { Far::Error(Far::FAR_RUNTIME_ERROR, "Fail in Map buffer\n"); buffer->Release(); return 0; } memcpy(resource.pData, data, size); deviceContext->Unmap(buffer, 0); return buffer; }
void MFVertex_DestroyIndexBufferPlatformSpecific(MFIndexBuffer *pIndexBuffer) { ID3D11Buffer *pIB = (ID3D11Buffer*)pIndexBuffer->pPlatformData; if(pIB) pIB->Release(); }
void MFVertex_DestroyVertexBufferPlatformSpecific(MFVertexBuffer *pVertexBuffer) { ID3D11Buffer *pVB = (ID3D11Buffer*)pVertexBuffer->pPlatformData; if(pVB) pVB->Release(); }
virtual ~dx11ShaderBufferCache() { if (VBO) VBO->Release(); }
void SuzanneDX::RenderShadowMaps() { D3D11_TEXTURE2D_DESC shadowMapDesc; ZeroMemory(&shadowMapDesc, sizeof(shadowMapDesc)); shadowMapDesc.Width = SHADOW_RESOLUTION; shadowMapDesc.Height = SHADOW_RESOLUTION; shadowMapDesc.MipLevels = 1; shadowMapDesc.ArraySize = 1; shadowMapDesc.Format = DXGI_FORMAT_R24G8_TYPELESS; shadowMapDesc.SampleDesc.Count = 1; shadowMapDesc.SampleDesc.Quality = 0; shadowMapDesc.Usage = D3D11_USAGE_DEFAULT; shadowMapDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; shadowMapDesc.CPUAccessFlags = 0; shadowMapDesc.MiscFlags = 0; D3D11_DEPTH_STENCIL_VIEW_DESC shadowMapDsvDesc; ZeroMemory(&shadowMapDsvDesc, sizeof(shadowMapDsvDesc)); shadowMapDsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; shadowMapDsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; shadowMapDsvDesc.Texture2D.MipSlice = 0; D3D11_SHADER_RESOURCE_VIEW_DESC shadowMapResourceDesc; ZeroMemory(&shadowMapResourceDesc, sizeof(shadowMapResourceDesc)); shadowMapResourceDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; shadowMapResourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shadowMapResourceDesc.Texture2D.MipLevels = 1; shadowMapResourceDesc.Texture2D.MostDetailedMip = 0; D3D11_VIEWPORT shadowMapViewport; shadowMapViewport.Width = (FLOAT)SHADOW_RESOLUTION; shadowMapViewport.Height = (FLOAT)SHADOW_RESOLUTION; shadowMapViewport.MinDepth = 0.0f; shadowMapViewport.MaxDepth = 1.0f; shadowMapViewport.TopLeftX = 0; shadowMapViewport.TopLeftY = 0; mDeviceContext->RSSetViewports(1, &shadowMapViewport); XMMATRIX shadowViewProjectionMatrices[NUMBER_OF_LIGHTS]; for (int i = 0; i < NUMBER_OF_LIGHTS; ++i) { ID3D11Texture2D* shadowMap; mDevice->CreateTexture2D(&shadowMapDesc, NULL, &shadowMap); ID3D11DepthStencilView* shadowMapDsv; mDevice->CreateDepthStencilView(shadowMap, &shadowMapDsvDesc, &shadowMapDsv); mDevice->CreateShaderResourceView(shadowMap, &shadowMapResourceDesc, &shadowMapResources[i]); mDeviceContext->OMSetRenderTargets(0, 0, shadowMapDsv); mDeviceContext->ClearDepthStencilView(shadowMapDsv, D3D11_CLEAR_DEPTH, 1.0f, 0); XMVECTOR lightInvDir = XMVector3Normalize(XMVectorSet(lighting.lights[i].position.x, lighting.lights[i].position.y, lighting.lights[i].position.z, 1.0f)); XMMATRIX shadowProjectionMatrix = XMMatrixOrthographicRH(20, 20, -10, 20); XMMATRIX shadowViewMatrix = XMMatrixLookAtRH(lightInvDir, XMVectorSet(0, 0, 0, 1), XMVectorSet(0, 1, 0, 1)); shadowViewProjectionMatrices[i] = shadowViewMatrix * shadowProjectionMatrix; ID3D11Buffer* shadowViewProjectionMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, shadowViewProjectionMatrices[i]); mDeviceContext->VSSetConstantBuffers(shadowViewProjectionMatrixBufferSlot, 1, &shadowViewProjectionMatrixBuffer); UINT stride = sizeof(Vertex); UINT offset = 0; for (ModelDX model : models) { mDeviceContext->IASetVertexBuffers(0, 1, &model.vertexBuffer, &stride, &offset); mDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); mDeviceContext->IASetInputLayout(model.inputLayout); mDeviceContext->VSSetShader(shadowVertexShader, 0, 0); mDeviceContext->PSSetShader(shadowPixelShader, 0, 0); mDeviceContext->VSSetConstantBuffers(modelMatrixBufferSlot, 1, &model.modelMatrixBuffer); mDeviceContext->Draw(model.vertexCount, 0); } shadowMap->Release(); shadowMapDsv->Release(); shadowViewProjectionMatrixBuffer->Release(); } mDeviceContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView); mDeviceContext->RSSetViewports(1, &mViewport); D3D11_BUFFER_DESC matrixDesc; ZeroMemory(&matrixDesc, sizeof(matrixDesc)); matrixDesc.ByteWidth = sizeof(XMMATRIX) * NUMBER_OF_LIGHTS; matrixDesc.Usage = D3D11_USAGE_DEFAULT; matrixDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; matrixDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA matrixData; ZeroMemory(&matrixData, sizeof(matrixData)); matrixData.pSysMem = &shadowViewProjectionMatrices[0]; ID3D11Buffer* matrixBuffer; mDevice->CreateBuffer(&matrixDesc, &matrixData, &matrixBuffer); mDeviceContext->VSSetConstantBuffers(shadowViewProjectionMatrixBufferSlot, 1, &matrixBuffer); matrixBuffer->Release(); XMMATRIX biasMatrix = XMMatrixSet( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0 ); ID3D11Buffer* shadowBiasMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, biasMatrix); mDeviceContext->VSSetConstantBuffers(shadowBiasMatrixBufferSlot, 1, &shadowBiasMatrixBuffer); shadowBiasMatrixBuffer->Release(); }
bool SuzanneDX::InitScene() { XMStoreFloat4(&up, XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f)); XMStoreFloat4(&eye, XMVectorSet(3.0f, 3.0f, 5.0f, 1.0f)); XMStoreFloat4(&right, XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f)); XMStoreFloat4(¢er, XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f)); ID3D11RasterizerState1 *rasterizerState; D3D11_RASTERIZER_DESC1 rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(rasterizerDesc)); rasterizerDesc.CullMode = D3D11_CULL_BACK; rasterizerDesc.FillMode = D3D11_FILL_SOLID; rasterizerDesc.FrontCounterClockwise = true; mDevice->CreateRasterizerState1(&rasterizerDesc, &rasterizerState); mDeviceContext->RSSetState(rasterizerState); rasterizerState->Release(); // COMPILE SHADERS D3DCompileFromFile(Util::s2ws(shaderPath + "TestSceneVert.hlsl").c_str(), NULL, NULL, "vertexShader", "vs_5_0", NULL, NULL, &vertexShaderBuffer, NULL); D3DCompileFromFile(Util::s2ws(shaderPath + "TestSceneFrag.hlsl").c_str(), NULL, NULL, "pixelShader", "ps_5_0", NULL, NULL, &pixelShaderBuffer, NULL); mDevice->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &vertexShader); mDevice->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &pixelShader); D3DCompileFromFile(Util::s2ws(shaderPath + "ShadowMappingVert.hlsl").c_str(), NULL, NULL, "vertexShader", "vs_5_0", NULL, NULL, &shadowVertexShaderBuffer, NULL); D3DCompileFromFile(Util::s2ws(shaderPath + "ShadowMappingFrag.hlsl").c_str(), NULL, NULL, "pixelShader", "ps_5_0", NULL, NULL, &shadowPixelShaderBuffer, NULL); mDevice->CreateVertexShader(shadowVertexShaderBuffer->GetBufferPointer(), shadowVertexShaderBuffer->GetBufferSize(), NULL, &shadowVertexShader); mDevice->CreatePixelShader(shadowPixelShaderBuffer->GetBufferPointer(), shadowPixelShaderBuffer->GetBufferSize(), NULL, &shadowPixelShader); // PREPARE MODELS std::vector<D3D11_INPUT_ELEMENT_DESC> vertexLayout; vertexLayout.push_back({ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }); vertexLayout.push_back({ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(Vertex().position), D3D11_INPUT_PER_VERTEX_DATA, 0 }); XMMATRIX modelMatrix; modelMatrix = XMMatrixTranslation(0.0f, 1.0f, 0.0f); models.push_back(ModelDX(modelPath + "monkey.bin", modelPath + "monkey2.mtl", mDevice, vertexShaderBuffer, vertexLayout, modelMatrix, true)); modelMatrix = XMMatrixScaling(5.0f, 5.0f, 5.0f); models.push_back(ModelDX(modelPath + "plane.bin", modelPath + "plane.mtl", mDevice, vertexShaderBuffer, vertexLayout, modelMatrix, true)); // PREPARE LIGHTING lighting.ambient = Vector4(0.1f, 0.1f, 0.1f, 1.0f); Light light1; light1.position = Vector4(-5.0f, 5.0f, 5.0f, 0.0f); light1.diffuse = Vector4(0.5f, 0.5f, 0.5f, 1.0f); light1.specular = Vector4(0.5f, 0.5f, 0.5f, 1.0f); Light light2; light2.position = Vector4(5.0f, 5.0f, 5.0f, 0.0f); light2.diffuse = Vector4(0.5f, 0.5f, 0.5f, 1.0f); light2.specular = Vector4(0.5f, 0.5f, 0.5f, 1.0f); lighting.lights[0] = light1; lighting.lights[1] = light2; D3D11_BUFFER_DESC lightDesc; ZeroMemory(&lightDesc, sizeof(lightDesc)); lightDesc.ByteWidth = sizeof(Lighting); lightDesc.Usage = D3D11_USAGE_DEFAULT; lightDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; lightDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA lightData; ZeroMemory(&lightData, sizeof(lightData)); lightData.pSysMem = &lighting; ID3D11Buffer* lightBuffer; mDevice->CreateBuffer(&lightDesc, &lightData, &lightBuffer); mDeviceContext->VSSetConstantBuffers(lightBufferSlot, 1, &lightBuffer); mDeviceContext->PSSetConstantBuffers(lightBufferSlot, 1, &lightBuffer); lightBuffer->Release(); RenderShadowMaps(); D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(samplerDesc)); samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.BorderColor[0] = 1.0f; samplerDesc.BorderColor[1] = 1.0f; samplerDesc.BorderColor[2] = 1.0f; samplerDesc.BorderColor[3] = 1.0f; samplerDesc.MinLOD = 0.f; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; samplerDesc.MipLODBias = 0.f; samplerDesc.MaxAnisotropy = 0; samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; mDevice->CreateSamplerState(&samplerDesc, &shadowMapSamplerState); // PREPARE MATERIAL BUFFER D3D11_BUFFER_DESC materialDesc; ZeroMemory(&materialDesc, sizeof(materialDesc)); materialDesc.ByteWidth = sizeof(Material); materialDesc.Usage = D3D11_USAGE_DEFAULT; materialDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; materialDesc.CPUAccessFlags = 0; mDevice->CreateBuffer(&materialDesc, NULL, &materialBuffer); mDeviceContext->PSSetConstantBuffers(materialBufferSlot, 1, &materialBuffer); // PREPARE VIEW AND PROJECTION XMMATRIX viewMatrix = XMMatrixLookAtRH(XMLoadFloat4(&eye), XMLoadFloat4(¢er), XMLoadFloat4(&up)); viewMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, viewMatrix); mDeviceContext->VSSetConstantBuffers(viewMatrixBufferSlot, 1, &viewMatrixBuffer); XMMATRIX projectionMatrix = XMMatrixPerspectiveFovRH(XMConvertToRadians(60.0f), 800 / 800, 1.0f, 500.0f); ID3D11Buffer* projectionMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, projectionMatrix); mDeviceContext->VSSetConstantBuffers(projectionMatrixBufferSlot, 1, &projectionMatrixBuffer); projectionMatrixBuffer->Release(); mDeviceContext->PSSetShaderResources(0, 2, &shadowMapResources[0]); mDeviceContext->PSSetSamplers(0, 1, &shadowMapSamplerState); return true; }
// // Draw frame into backbuffer // DUPL_RETURN OUTPUTMANAGER::DrawFrame() { HRESULT hr; // If window was resized, resize swapchain if (m_NeedsResize) { DUPL_RETURN Ret = ResizeSwapChain(); if (Ret != DUPL_RETURN_SUCCESS) { return Ret; } m_NeedsResize = false; } // Vertices for drawing whole texture VERTEX Vertices[NUMVERTICES] = { {XMFLOAT3(-1.0f, -1.0f, 0), XMFLOAT2(0.0f, 1.0f)}, {XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)}, {XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)}, {XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)}, {XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)}, {XMFLOAT3(1.0f, 1.0f, 0), XMFLOAT2(1.0f, 0.0f)}, }; D3D11_TEXTURE2D_DESC FrameDesc; m_SharedSurf->GetDesc(&FrameDesc); D3D11_SHADER_RESOURCE_VIEW_DESC ShaderDesc; ShaderDesc.Format = FrameDesc.Format; ShaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; ShaderDesc.Texture2D.MostDetailedMip = FrameDesc.MipLevels - 1; ShaderDesc.Texture2D.MipLevels = FrameDesc.MipLevels; // Create new shader resource view ID3D11ShaderResourceView* ShaderResource = nullptr; hr = m_Device->CreateShaderResourceView(m_SharedSurf, &ShaderDesc, &ShaderResource); if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to create shader resource when drawing a frame", L"Error", hr, SystemTransitionsExpectedErrors); } // Set resources UINT Stride = sizeof(VERTEX); UINT Offset = 0; FLOAT blendFactor[4] = {0.f, 0.f, 0.f, 0.f}; m_DeviceContext->OMSetBlendState(nullptr, blendFactor, 0xffffffff); m_DeviceContext->OMSetRenderTargets(1, &m_RTV, nullptr); m_DeviceContext->VSSetShader(m_VertexShader, nullptr, 0); m_DeviceContext->PSSetShader(m_PixelShader, nullptr, 0); m_DeviceContext->PSSetShaderResources(0, 1, &ShaderResource); m_DeviceContext->PSSetSamplers(0, 1, &m_SamplerLinear); m_DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D11_BUFFER_DESC BufferDesc; RtlZeroMemory(&BufferDesc, sizeof(BufferDesc)); BufferDesc.Usage = D3D11_USAGE_DEFAULT; BufferDesc.ByteWidth = sizeof(VERTEX) * NUMVERTICES; BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; BufferDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; RtlZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = Vertices; ID3D11Buffer* VertexBuffer = nullptr; // Create vertex buffer hr = m_Device->CreateBuffer(&BufferDesc, &InitData, &VertexBuffer); if (FAILED(hr)) { ShaderResource->Release(); ShaderResource = nullptr; return ProcessFailure(m_Device, L"Failed to create vertex buffer when drawing a frame", L"Error", hr, SystemTransitionsExpectedErrors); } m_DeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &Stride, &Offset); // Draw textured quad onto render target m_DeviceContext->Draw(NUMVERTICES, 0); VertexBuffer->Release(); VertexBuffer = nullptr; // Release shader resource ShaderResource->Release(); ShaderResource = nullptr; return DUPL_RETURN_SUCCESS; }
int _tmain(int /*argc*/, _TCHAR* /*argv[]*/) { // GROUP_SIZE_X defined in kernel.hlsl must match the // groupSize declared here. size_t const groupSize = 512; size_t const numGroups = 16; size_t const dimension = numGroups*groupSize; // Create a D3D11 device and immediate context. // TODO: The code below uses the default video adapter, with the // default set of feature levels. Please see the MSDN docs if // you wish to control which adapter and feature level are used. D3D_FEATURE_LEVEL featureLevel; ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, 0, D3D11_SDK_VERSION, &device, &featureLevel, &context); if (FAILED(hr)) { printf("D3D11CreateDevice failed with return code %x\n", hr); return hr; } // Create system memory and fill it with our initial data. Note that // these data structures aren't really necessary , it's just a demonstration // of how you can take existing data structures you might have and copy // their data to/from GPU computations. std::vector<float> x(dimension); std::vector<float> y(dimension); std::vector<float> z(dimension); float const a = 2.0f; for (size_t i = 0; i < dimension; ++ i) { x[i] = static_cast<float>(i); y[i] = 100 - static_cast<float>(i); } // Create structured buffers for the "x" and "y" vectors. D3D11_BUFFER_DESC inputBufferDesc; inputBufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // The buffers are read-only by the GPU, writeable by the CPU. // TODO: If you will never again upate the data in a GPU buffer, // you might want to look at using a D3D11_SUBRESOURCE_DATA here to // provide the initialization data instead of doing the mapping // and copying that happens below. inputBufferDesc.Usage = D3D11_USAGE_DYNAMIC; inputBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; inputBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; inputBufferDesc.StructureByteStride = sizeof(float); inputBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* xBuffer = nullptr; hr = device->CreateBuffer(&inputBufferDesc, NULL, &xBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for x buffer with return code %x\n", hr); return hr; } // We can re-use inputBufferDesc here because the layout and usage of the x // and y buffers is exactly the same. ID3D11Buffer* yBuffer = nullptr; hr = device->CreateBuffer(&inputBufferDesc, NULL, &yBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for x buffer with return code %x\n", hr); return hr; } // Create shader resource views for the "x" and "y" buffers. // TODO: You can optionally provide a D3D11_SHADER_RESOURCE_VIEW_DESC // as the second parameter if you need to use only part of the buffer // inside the compute shader. ID3D11ShaderResourceView* xSRV = nullptr; hr = device->CreateShaderResourceView(xBuffer, NULL, &xSRV); if (FAILED(hr)) { printf("CreateShaderResourceView failed for x buffer with return code %x\n", hr); return hr; } ID3D11ShaderResourceView* ySRV = nullptr; hr = device->CreateShaderResourceView(yBuffer, NULL, &ySRV); if (FAILED(hr)) { printf("CreateShaderResourceView failed for y buffer with return code %x\n", hr); return hr; } // Create a structured buffer for the "z" vector. This buffer needs to be // writeable by the GPU, so we can't create it with CPU read/write access. D3D11_BUFFER_DESC outputBufferDesc; outputBufferDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; outputBufferDesc.Usage = D3D11_USAGE_DEFAULT; outputBufferDesc.CPUAccessFlags = 0; outputBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; outputBufferDesc.StructureByteStride = sizeof(float); outputBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* zBuffer = nullptr; hr = device->CreateBuffer(&outputBufferDesc, NULL, &zBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for z buffer with return code %x\n", hr); return hr; } // Create an unordered access view for the "z" vector. D3D11_UNORDERED_ACCESS_VIEW_DESC outputUAVDesc; outputUAVDesc.Buffer.FirstElement = 0; outputUAVDesc.Buffer.Flags = 0; outputUAVDesc.Buffer.NumElements = dimension; outputUAVDesc.Format = DXGI_FORMAT_UNKNOWN; outputUAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; ID3D11UnorderedAccessView* zBufferUAV; hr = device->CreateUnorderedAccessView(zBuffer, &outputUAVDesc, &zBufferUAV); if (FAILED(hr)) { printf("CreateUnorderedAccessView failed for z buffer with return code %x\n", hr); return hr; } // Create a staging buffer, which will be used to copy back from zBuffer. D3D11_BUFFER_DESC stagingBufferDesc; stagingBufferDesc.BindFlags = 0; stagingBufferDesc.Usage = D3D11_USAGE_STAGING; stagingBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; stagingBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; stagingBufferDesc.StructureByteStride = sizeof(float); stagingBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* stagingBuffer; hr = device->CreateBuffer(&stagingBufferDesc, NULL, &stagingBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for staging buffer with return code %x\n", hr); return hr; } // Create a constant buffer (this buffer is used to pass the constant // value 'a' to the kernel as cbuffer Constants). D3D11_BUFFER_DESC cbDesc; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.Usage = D3D11_USAGE_DYNAMIC; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbDesc.MiscFlags = 0; // Even though the constant buffer only has one float, DX expects // ByteWidth to be a multiple of 4 floats (i.e., one 128-bit register). cbDesc.ByteWidth = sizeof(float)*4; ID3D11Buffer* constantBuffer = nullptr; hr = device->CreateBuffer( &cbDesc, NULL, &constantBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for constant buffer with return code %x\n", hr); return hr; } // Map the constant buffer and set the constant value 'a'. D3D11_MAPPED_SUBRESOURCE mappedResource; context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* constants = reinterpret_cast<float*>(mappedResource.pData); constants[0] = a; constants = nullptr; context->Unmap(constantBuffer, 0); // Map the x buffer and copy our data into it. context->Map(xBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* xvalues = reinterpret_cast<float*>(mappedResource.pData); memcpy(xvalues, &x[0], sizeof(float)*x.size()); xvalues = nullptr; context->Unmap(xBuffer, 0); // Map the y buffer and copy our data into it. context->Map(yBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* yvalues = reinterpret_cast<float*>(mappedResource.pData); memcpy(yvalues, &y[0], sizeof(float)*y.size()); yvalues = nullptr; context->Unmap(yBuffer, 0); // Compile the compute shader into a blob. ID3DBlob* errorBlob = nullptr; ID3DBlob* shaderBlob = nullptr; hr = D3DX11CompileFromFile(L"kernel.hlsl", NULL, NULL, "saxpy", "cs_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &shaderBlob, &errorBlob, NULL); if (FAILED(hr)) { // Print out the error message if there is one. if (errorBlob) { char const* message = (char*)errorBlob->GetBufferPointer(); printf("kernel.hlsl failed to compile; error message:\n"); printf("%s\n", message); errorBlob->Release(); } return hr; } // Create a shader object from the compiled blob. ID3D11ComputeShader* computeShader; hr = device->CreateComputeShader(shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), NULL, &computeShader); if (FAILED(hr)) { printf("CreateComputeShader failed with return code %x\n", hr); return hr; } // Make the shader active. context->CSSetShader(computeShader, NULL, 0); // Attach the z buffer to the output via its unordered access view. UINT initCounts = 0xFFFFFFFF; context->CSSetUnorderedAccessViews(0, 1, &zBufferUAV, &initCounts); // Attach the input buffers via their shader resource views. context->CSSetShaderResources(0, 1, &xSRV); context->CSSetShaderResources(1, 1, &ySRV); // Attach the constant buffer context->CSSetConstantBuffers(0, 1, &constantBuffer); // Execute the shader, in 'numGroups' groups of 'groupSize' threads each. context->Dispatch(numGroups, 1, 1); // Copy the z buffer to the staging buffer so that we can // retrieve the data for accesss by the CPU. context->CopyResource(stagingBuffer, zBuffer); // Map the staging buffer for reading. context->Map(stagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); float* zData = reinterpret_cast<float*>(mappedResource.pData); memcpy(&z[0], zData, sizeof(float)*z.size()); zData = nullptr; context->Unmap(stagingBuffer, 0); // Now compare the GPU results against expected values. bool resultOK = true; for (size_t i = 0; i < x.size(); ++ i) { // NOTE: This comparison assumes the GPU produces *exactly* the // same result as the CPU. In general, this will not be the case // with floating-point calculations. float const expected = a*x[i] + y[i]; if (z[i] != expected) { printf("Unexpected result at position %lu: expected %.7e, got %.7e\n", i, expected, z[i]); resultOK = false; } } if (!resultOK) { printf("GPU results differed from the CPU results.\n"); OutputDebugStringA("GPU results differed from the CPU results.\n"); return 1; } printf("GPU output matched the CPU results.\n"); OutputDebugStringA("GPU output matched the CPU results.\n"); // Disconnect everything from the pipeline. ID3D11UnorderedAccessView* nullUAV = nullptr; context->CSSetUnorderedAccessViews( 0, 1, &nullUAV, &initCounts); ID3D11ShaderResourceView* nullSRV = nullptr; context->CSSetShaderResources(0, 1, &nullSRV); context->CSSetShaderResources(1, 1, &nullSRV); ID3D11Buffer* nullBuffer = nullptr; context->CSSetConstantBuffers(0, 1, &nullBuffer); // Release resources. Again, note that none of the error checks above // release resources that have been allocated up to this point, so the // sample doesn't clean up after itself correctly unless everything succeeds. computeShader->Release(); shaderBlob->Release(); constantBuffer->Release(); stagingBuffer->Release(); zBufferUAV->Release(); zBuffer->Release(); xSRV->Release(); xBuffer->Release(); ySRV->Release(); yBuffer->Release(); context->Release(); device->Release(); return 0; }
void* VertexBuffer::MapDeviceBuffer(EAccessFlags access, unsigned int offset, unsigned int size) { OGSAssertReturnPtr((offset+size) <= (unsigned int)mOwnerBuffer->CapacityInFloats()); OGSAssertReturnPtr(mMapAccess == EAccessNone); // must not already be mapped OGSAssertReturnPtr(mBuffer != NULL); //get d3d11 access flag and map flag, also check if it need a copy operation D3D11_MAP map; unsigned int cpu_access = 0; bool needcopy = false; // This is the only assertion we can make on the mAccess, because we do not follow the DX11 spec. // For example, to map a buffer with D3D11_MAP_READ map flag, DX11 spec requires D3D11_CPU_ACCESS_READ // CPU access flag and D3D11_USAGE_STAGING usage flag in creation time, but we do not. if (mOwnerBuffer->Access() == EAccessNone) { Sys::Warning(L"DX11: Cannot map a buffer created with no CPU access."); return NULL; } D3D11_BUFFER_DESC desc; mBuffer->GetDesc(&desc); switch (access) { case ReadOnly: { map = D3D11_MAP_READ; cpu_access = D3D11_CPU_ACCESS_READ; //only staging usage can be mapped by CPU read if (desc.Usage != D3D11_USAGE_STAGING) needcopy = true; break; } case ReadWrite: { map = D3D11_MAP_READ_WRITE; cpu_access = D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE; //only staging usage can be mapped by CPU read if (desc.Usage != D3D11_USAGE_STAGING) needcopy = true; break; } case WriteOnly: { map = D3D11_MAP_WRITE; cpu_access = D3D11_CPU_ACCESS_WRITE; //only dynamic/staging usage can be mapped by CPU write if (desc.Usage != D3D11_USAGE_STAGING) needcopy = true; break; } case WriteDiscard: { map = D3D11_MAP_WRITE_DISCARD; cpu_access = D3D11_CPU_ACCESS_WRITE; //only dynamic usage can be mapped by CPU write discard if (desc.Usage != D3D11_USAGE_DYNAMIC) { Sys::Warning(L"Can't map this map with access flag WriteDiscard."); return NULL; } break; } case WriteNoOverwrite: { map = D3D11_MAP_WRITE_NO_OVERWRITE; cpu_access = D3D11_CPU_ACCESS_WRITE; //only dynamic usage can be mapped by CPU write no overwrite if (desc.Usage != D3D11_USAGE_DYNAMIC) { Sys::Warning(L"Can't map this map with access flag WriteNoOverwrite."); return NULL; } break; } default: ErrorReturnPtr(); } // set up the buffer to map ID3D11Buffer* buffer = mBuffer; //get dx11 device and context ID3D11Device* pDevice = (ID3D11Device*)(mVD->GPUDevice()); if (needcopy) { //warning information // It turns out this condition is fine for DX10 (or at least no worse that DX9), // i.e. it's normal to do this sort of mapping, according to Adam. Warning removed. //Sys::Warning(L"Mapping flag doesn't match resource usage,the map will be a low performance operation"); //check if staging buffer in NULL, or the vertex buffer is in map now OGSAssertReturnPtr(mStagingBuffer == NULL); //create staging buffer description D3D11_BUFFER_DESC bufferDesc; bufferDesc.ByteWidth = sizeof(float) * mOwnerBuffer->CapacityInFloats(); bufferDesc.BindFlags = 0; // can't bind a staging resource bufferDesc.Usage = D3D11_USAGE_STAGING; bufferDesc.CPUAccessFlags = cpu_access; bufferDesc.MiscFlags = 0; //create a staging buffer for data-copy HRESULT hr; OGS_DEVICECALLDX11(pDevice->CreateBuffer( &bufferDesc, NULL, &buffer ), return NULL); if ( FAILED(hr)|| buffer == NULL ) { OGS_INTERPRET_ERROR_CODE_DX11( L"CreateBuffer() staging buffer", hr ); return NULL; } { // Use lock in virtual device to protect device context operation VD_TRYTOLOCK(mVD); // copy the vb to the staging buffer DX_IMMEDIATECONTEXT(mVD)->CopyResource( buffer, mBuffer ); } mStagingBuffer = buffer; // add the size of staging buffer to memory monitor OGS::Objects::ObjModel::MemoryMonitor().AddToDeviceMemory(mOwnerBuffer->CapacityInFloats() * sizeof(float)); } HRESULT hr; // now map the buffer or the staging buffer D3D11_MAPPED_SUBRESOURCE mappedSub; { //TODO DX11 MULTITHREADING // Buffers with DYNAMIC_USAGE flags can be Mapped/Unmapped on a Deferred Context. // But there are some restrictions on how WRITE_DISCARD and WRITE_NO_OVERWRITE flags should be used. // We currently don't support all workflows for using WRITE_DISCARD and WRITE_NO_OVERWRITE in Deferred Context. // Once this support is enabled we can do Map/Unmap on Deferred Context. { // Use lock in virtual device to protect device context operation VD_TRYTOLOCK(mVD); hr=DX_IMMEDIATECONTEXT(mVD)->Map( buffer, 0, map, 0, &mappedSub ); } } if( FAILED(hr) ) { OGS_INTERPRET_ERROR_CODE_DX11( L"Map() vertex", hr ); //release created staging buffer if (mStagingBuffer) { buffer->Release(); mStagingBuffer = NULL; } if(hr == DXGI_ERROR_DEVICE_REMOVED) { // The video card has been physically removed from the system, a driver upgrade for the // GPU has occurred, or the GPU driver was disabled. // At this point we need to release this and the device will have to be recreated by // the client application using the DeviceRemovedCB() callback. // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509553(v=vs.85).aspx OGSAssert(mVD != NULL); ID3D11Device * const pDevice = static_cast<ID3D11Device * const>(mVD->GPUDevice()); static_cast<DeviceContextDx11*>(mVD)->OnDeviceRemoved(pDevice); } return NULL; } float* dstBuffer = (float*)mappedSub.pData; mMapAccess = access; mOwnerBuffer->MappedBuffer(dstBuffer); return dstBuffer + offset; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) { DXTInputHandlerDefault inputHandler; DXTWindowEventHandlerDefault eventHandler; DXTWindow window(hInstance, &inputHandler, &eventHandler); DXTRenderParams params; params.Extent = { 800, 600 }; params.UseVSync = true; params.Windowed = true; HRESULT result; result = window.Initialize(params, "DXT Example (DirectX 11)"); if (SUCCEEDED(result)) { ID3D11Device* device; ID3D11DeviceContext* context; IDXGISwapChain* swapChain; result = DXTInitDevice(params, &window, &swapChain, &device, &context); if (SUCCEEDED(result)) { eventHandler.SetSwapChain(swapChain); FLOAT clearColor[] = { 0.5f, 0.5f, 1.0f, 1.0f }; D3D11_INPUT_ELEMENT_DESC inputDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(float) * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(float) * 5, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT elementCount = 3; UINT stride = 8 * sizeof(FLOAT); UINT offset = 0; UINT indexCount = 0; FLOAT deltaTime = 0.016f; DXTSphericalCamera camera; DXTFirstPersonCameraController cameraController(&camera, &inputHandler); inputHandler.AddInputInterface(&cameraController); cameraController.Velocity = 40.0f; cameraController.RotationVelocity = 0.005f; camera.Position = DirectX::XMFLOAT3(20.0f, 20.0f, 20.0f); camera.LookAt(DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f)); ID3D11RenderTargetView* renderTargetView; ID3D11Texture2D* depthBuffer; ID3D11DepthStencilView* depthBufferView; ID3D11VertexShader* vertexShader; ID3D11PixelShader* pixelShader; DXTBytecodeBlob vertexBytecode; ID3D11DepthStencilState* depthState; ID3D11RasterizerState* rasterizerState; ID3D11Buffer* vertexBuffer; ID3D11Buffer* indexBuffer; ID3D11InputLayout* inputLayout; ID3D11Buffer* transformBuffer; DXTCreateRenderTargetFromBackBuffer(swapChain, device, &renderTargetView); DXTCreateDepthStencilBuffer(device, params.Extent.Width, params.Extent.Height, DXGI_FORMAT_D24_UNORM_S8_UINT, &depthBuffer, &depthBufferView); DXTVertexShaderFromFile(device, "VertexShader.cso", &vertexShader, &vertexBytecode); DXTPixelShaderFromFile(device, "PixelShader.cso", &pixelShader); DXTCreateDepthStencilStateDepthTestEnabled(device, &depthState); DXTCreateRasterizerStateSolid(device, &rasterizerState); DXTLoadStaticMeshFromFile(device, "mesh.ase", DXTVertexAttributePosition | DXTVertexAttributeUV | DXTVertexAttributeNormal, DXTIndexTypeShort, &vertexBuffer, &indexBuffer, &indexCount); DXTCreateBuffer(device, sizeof(DirectX::XMFLOAT4X4) * 2, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, D3D11_USAGE_DYNAMIC, &transformBuffer); device->CreateInputLayout(inputDesc, elementCount, vertexBytecode.Bytecode, vertexBytecode.BytecodeLength, &inputLayout); vertexBytecode.Destroy(); window.Present(false); while (!window.QuitMessageReceived()) { window.MessagePump(); if (inputHandler.IsKeyDown(VK_ESCAPE)) break; cameraController.Update(deltaTime); XMFLOAT4X4 ViewProj; XMFLOAT4X4 World; camera.GetViewProjectionMatrix(&ViewProj, params.Extent); XMStoreFloat4x4(&World, XMMatrixIdentity()); D3D11_MAPPED_SUBRESOURCE subres; context->Map(transformBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subres); XMFLOAT4X4* ptr = (XMFLOAT4X4*)subres.pData; ptr[0] = World; ptr[1] = ViewProj; context->Unmap(transformBuffer, 0); D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (FLOAT)params.Extent.Width, (FLOAT)params.Extent.Height, 0.0f, 1.0f }; context->ClearRenderTargetView(renderTargetView, clearColor); context->ClearDepthStencilView(depthBufferView, D3D11_CLEAR_DEPTH, 1.0f, 0); context->OMSetDepthStencilState(depthState, 0); context->OMSetRenderTargets(1, &renderTargetView, depthBufferView); context->RSSetState(rasterizerState); context->RSSetViewports(1, &viewport); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); context->IASetInputLayout(inputLayout); context->VSSetShader(vertexShader, nullptr, 0); context->PSSetShader(pixelShader, nullptr, 0); context->VSSetConstantBuffers(0, 1, &transformBuffer); context->DrawIndexed(indexCount, 0, 0); swapChain->Present(1, 0); } swapChain->SetFullscreenState(false, nullptr); transformBuffer->Release(); depthBufferView->Release(); depthBuffer->Release(); inputLayout->Release(); vertexBuffer->Release(); indexBuffer->Release(); depthState->Release(); rasterizerState->Release(); vertexShader->Release(); pixelShader->Release(); renderTargetView->Release(); swapChain->Release(); context->Release(); device->Release(); } window.Destroy(); } }
bool ContentPackage::LoadMesh(const std::string& contentLocation, StaticMesh** meshOut) { OutputDebugString("Loading resource "); OutputDebugString(contentLocation.c_str()); OutputDebugString("\n"); if (vertexStrideFloat == 0) { OutputDebugString("Vertex layout has not been set!\n"); return false; } auto findResult = staticMeshes.find(contentLocation); if (findResult != staticMeshes.end()) { *meshOut = findResult->second; return true; } Assimp::Importer importer; const aiScene* scene = importer.ReadFile(contentLocation.c_str(), (aiProcessPreset_TargetRealtime_Fast | aiProcess_FlipUVs | aiProcess_PreTransformVertices)); if (scene == nullptr) return false; float* meshData = nullptr; if (!scene->HasMeshes()) { OutputDebugString("Scene does not have meshes!\n"); return false; } size_t dataSize = 0; for (size_t i = 0; i < scene->mNumMeshes; ++i) { auto mesh = scene->mMeshes[i]; if (!mesh->HasPositions() && (offsets.position != VERTEX_ATTRIBUTE_DISABLED)) { OutputDebugString("Mesh is missing positions!\n"); return false; } if (!mesh->HasTextureCoords(0) && (offsets.texCoord != VERTEX_ATTRIBUTE_DISABLED)) { OutputDebugString("Mesh is missing texture coordinates at location 0!\n"); return false; } if (!mesh->HasNormals() && (offsets.normal != VERTEX_ATTRIBUTE_DISABLED)) { OutputDebugString("Mesh is missing normals!\n"); return false; } if (!mesh->HasTangentsAndBitangents() && ((offsets.tangent != VERTEX_ATTRIBUTE_DISABLED) || (offsets.bitangent != VERTEX_ATTRIBUTE_DISABLED))) { OutputDebugString("Mesh is missing tangets or bitangents!\n"); return false; } dataSize += mesh->mNumVertices; } dataSize *= vertexStrideFloat; meshData = new float[dataSize]; DXGI_FORMAT indexFormat; if (dataSize <= UINT16_MAX) indexFormat = DXGI_FORMAT_R16_UINT; else indexFormat = DXGI_FORMAT_R32_UINT; size_t meshOffset = 0; for (size_t i = 0; i < scene->mNumMeshes; ++i) { auto mesh = scene->mMeshes[i]; size_t meshDataSize = vertexStrideFloat * mesh->mNumVertices; if (offsets.position != VERTEX_ATTRIBUTE_DISABLED) { for (size_t dataLoc = meshOffset + offsets.position, vertexId = offsets.position, end = meshOffset + meshDataSize; dataLoc < end; dataLoc += vertexStrideFloat, ++vertexId) { meshData[dataLoc] = mesh->mVertices[vertexId].x; meshData[dataLoc + 1] = mesh->mVertices[vertexId].y; meshData[dataLoc + 2] = mesh->mVertices[vertexId].z; } } if (offsets.texCoord != VERTEX_ATTRIBUTE_DISABLED) { for (size_t dataLoc = meshOffset + offsets.texCoord, vertexId = 0, end = meshOffset + meshDataSize; dataLoc < end; dataLoc += vertexStrideFloat, ++vertexId) { meshData[dataLoc] = mesh->mTextureCoords[0][vertexId].x; meshData[dataLoc + 1] = mesh->mTextureCoords[0][vertexId].y; } } if (offsets.normal != VERTEX_ATTRIBUTE_DISABLED) { for (size_t dataLoc = meshOffset + offsets.normal, vertexId = 0, end = meshOffset + meshDataSize; dataLoc < end; dataLoc += vertexStrideFloat, ++vertexId) { meshData[dataLoc] = mesh->mNormals[vertexId].x; meshData[dataLoc + 1] = mesh->mNormals[vertexId].y; meshData[dataLoc + 2] = mesh->mNormals[vertexId].z; } } if (offsets.tangent != VERTEX_ATTRIBUTE_DISABLED) { for (size_t dataLoc = meshOffset + offsets.tangent, vertexId = 0, end = meshOffset + meshDataSize; dataLoc < end; dataLoc += vertexStrideFloat, ++vertexId) { meshData[dataLoc] = mesh->mTangents[vertexId].x; meshData[dataLoc + 1] = mesh->mTangents[vertexId].y; meshData[dataLoc + 2] = mesh->mTangents[vertexId].z; } } if (offsets.bitangent != VERTEX_ATTRIBUTE_DISABLED) { for (size_t dataLoc = meshOffset + offsets.bitangent, vertexId = 0, end = meshOffset + meshDataSize; dataLoc < end; dataLoc += vertexStrideFloat, ++vertexId) { meshData[dataLoc] = mesh->mBitangents[vertexId].x; meshData[dataLoc + 1] = mesh->mBitangents[vertexId].y; meshData[dataLoc + 2] = mesh->mBitangents[vertexId].z; } } meshOffset += mesh->mNumVertices * vertexStrideFloat; } size_t indexCount = 0; for (size_t i = 0; i < scene->mNumMeshes; ++i) indexCount += scene->mMeshes[i]->mNumFaces * 3; void* meshIndices = nullptr; if (indexFormat == DXGI_FORMAT_R16_UINT) { uint16_t* meshIndices16 = new uint16_t[indexCount]; meshIndices = meshIndices16; size_t indexOffset = 0; meshOffset = 0; for (size_t i = 0; i < scene->mNumMeshes; ++i) { auto mesh = scene->mMeshes[i]; for (size_t faceId = 0, indexId = indexOffset; faceId < mesh->mNumFaces; ++faceId) { meshIndices16[indexId++] = mesh->mFaces[faceId].mIndices[0] + static_cast<uint16_t>(meshOffset); meshIndices16[indexId++] = mesh->mFaces[faceId].mIndices[1] + static_cast<uint16_t>(meshOffset); meshIndices16[indexId++] = mesh->mFaces[faceId].mIndices[2] + static_cast<uint16_t>(meshOffset); } indexOffset += mesh->mNumFaces * 3; meshOffset += mesh->mNumVertices * vertexStrideFloat; } } else { uint32_t* meshIndices32 = new uint32_t[indexCount]; meshIndices = meshIndices32; size_t indexOffset = 0; meshOffset = 0; for (size_t i = 0; i < scene->mNumMeshes; ++i) { auto mesh = scene->mMeshes[i]; for (size_t faceId = 0, indexId = indexOffset; faceId < mesh->mNumFaces; ++faceId) { meshIndices32[indexId++] = mesh->mFaces[faceId].mIndices[0] + meshOffset; meshIndices32[indexId++] = mesh->mFaces[faceId].mIndices[1] + meshOffset; meshIndices32[indexId++] = mesh->mFaces[faceId].mIndices[2] + meshOffset; } indexOffset += mesh->mNumFaces * 3; meshOffset += mesh->mNumVertices * vertexStrideFloat; } } D3D11_BUFFER_DESC bufferDesc; bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufferDesc.ByteWidth = sizeof(float) * dataSize; bufferDesc.CPUAccessFlags = 0; bufferDesc.MiscFlags = 0; bufferDesc.StructureByteStride = 0; bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; D3D11_SUBRESOURCE_DATA bufferData; ZeroMemory(&bufferData, sizeof(bufferData)); bufferData.pSysMem = meshData; ID3D11Buffer* vertexBuffer; HRESULT result = device->CreateBuffer(&bufferDesc, &bufferData, &vertexBuffer); if (FAILED(result)) { delete[] meshData; delete[] meshIndices; return false; } bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; if (indexFormat == DXGI_FORMAT_R16_UINT) bufferDesc.ByteWidth = indexCount * sizeof(uint16_t); else bufferDesc.ByteWidth = indexCount * sizeof(uint32_t); bufferData.pSysMem = meshIndices; ID3D11Buffer* indexBuffer; result = device->CreateBuffer(&bufferDesc, &bufferData, &indexBuffer); delete[] meshData; delete[] meshIndices; if (FAILED(result)) { vertexBuffer->Release(); return false; } auto infinity = numeric_limits<float>::infinity(); Bounds bounds = { { infinity, infinity, infinity }, { -infinity, -infinity, -infinity } }; for (size_t i = 0; i < scene->mNumMeshes; ++i) { auto mesh = scene->mMeshes[i]; for (size_t vertexId = 0; vertexId < mesh->mNumVertices; ++vertexId) { auto vertex = mesh->mVertices[vertexId]; if (vertex.x > bounds.Upper.x) bounds.Upper.x = vertex.x; if (vertex.y > bounds.Upper.y) bounds.Upper.y = vertex.y; if (vertex.z > bounds.Upper.z) bounds.Upper.z = vertex.z; if (vertex.x < bounds.Lower.x) bounds.Lower.x = vertex.x; if (vertex.y < bounds.Lower.y) bounds.Lower.y = vertex.y; if (vertex.z < bounds.Lower.z) bounds.Lower.z = vertex.z; } } stringstream strstream; strstream << "Computed Mesh Bounds : { (" << bounds.Lower.x << ", " << bounds.Lower.y << ", " << bounds.Lower.z << "), (" << bounds.Upper.x << ", " << bounds.Upper.y << ", " << bounds.Upper.z << ") }\n"; OutputDebugString(strstream.str().c_str()); *meshOut = new StaticMesh(vertexBuffer, indexBuffer, indexCount, 0, bounds, indexFormat); staticMeshes[contentLocation] = *meshOut; #if defined(ENABLE_DIRECT3D_DEBUG) && defined(ENABLE_NAMED_OBJECTS) stringstream strstreamVert; strstreamVert << contentLocation << " : Vertex Buffer"; SetDebugObjectName(vertexBuffer, strstreamVert.str()); stringstream strstreamIndex; strstreamIndex << contentLocation << " : Index Buffer"; SetDebugObjectName(indexBuffer, strstreamIndex.str()); #endif return true; }
bool TestTriangleStripsDX::InitScene() { XMStoreFloat4(&up, XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f)); XMStoreFloat4(&eye, XMVectorSet(0.0f, 18.0f, 18.0f, 1.0f)); XMStoreFloat4(&right, XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f)); XMStoreFloat4(¢er, XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f)); bg[0] = bgColor.r; bg[1] = bgColor.g; bg[2] = bgColor.b; bg[3] = bgColor.a; ID3D11RasterizerState1 *rasterizerState; D3D11_RASTERIZER_DESC1 rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(rasterizerDesc)); rasterizerDesc.CullMode = D3D11_CULL_NONE; rasterizerDesc.FillMode = D3D11_FILL_SOLID; rasterizerDesc.FrontCounterClockwise = true; mDevice->CreateRasterizerState1(&rasterizerDesc, &rasterizerState); mDeviceContext->RSSetState(rasterizerState); rasterizerState->Release(); BinaryIO::ReadVector4s(binaryPath + "triangle_strip_plane.bin", vertices); D3D11_INPUT_ELEMENT_DESC vertexLayout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; D3DCompileFromFile(Util::s2ws(shaderPath + "TestTriangleStripsVert.hlsl").c_str(), NULL, NULL, "vertexShader", "vs_5_0", NULL, NULL, &vertexShaderBuffer, NULL); D3DCompileFromFile(Util::s2ws(shaderPath + "TestTriangleStripsFrag.hlsl").c_str(), NULL, NULL, "pixelShader", "ps_5_0", NULL, NULL, &pixelShaderBuffer, NULL); mDevice->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &vertexShader); mDevice->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &pixelShader); D3D11_BUFFER_DESC vertexBufferDesc; ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc)); vertexBufferDesc.ByteWidth = vertices.size() * sizeof(Vector4); vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA vertexBufferData; ZeroMemory(&vertexBufferData, sizeof(vertexBufferData)); vertexBufferData.pSysMem = &vertices[0]; mDevice->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &vertexBuffer); mDevice->CreateInputLayout(vertexLayout, 1, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &inputLayout); // UPLOAD MVP MATRICES XMMATRIX modelMatrix = XMMatrixIdentity(); XMMATRIX viewMatrix = XMMatrixLookAtRH(XMLoadFloat4(&eye), XMLoadFloat4(¢er), XMLoadFloat4(&up)); XMMATRIX projectionMatrix = XMMatrixPerspectiveFovRH(XMConvertToRadians(60.0f), 800 / 800, 1.0f, 500.0f); ID3D11Buffer* modelMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, modelMatrix); mDeviceContext->VSSetConstantBuffers(modelMatrixBufferSlot, 1, &modelMatrixBuffer); modelMatrixBuffer->Release(); viewMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, viewMatrix); mDeviceContext->VSSetConstantBuffers(viewMatrixBufferSlot, 1, &viewMatrixBuffer); viewMatrixBuffer->Release(); ID3D11Buffer* projectionMatrixBuffer = DXUtil::CreateMatrixBuffer(mDevice, projectionMatrix); mDeviceContext->VSSetConstantBuffers(projectionMatrixBufferSlot, 1, &projectionMatrixBuffer); projectionMatrixBuffer->Release(); return true; }