Commit ca71c75d by Bryan Bernhart (Intel Americas Inc) Committed by Commit Bot

Fix error handling of ID3D11DeviceContext::Map

Refactors error handling should map() fail to avoid crashing during a device error event. BUG=angleproject:2284 Change-Id: Ib1eb676860fa5c3a81e523f49aab82b7e6700f73 Reviewed-on: https://chromium-review.googlesource.com/826485Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent ae4dbf32
......@@ -1002,7 +1002,6 @@ gl::Error Blit11::swizzleTexture(const gl::Context *context,
{
ANGLE_TRY(initResources());
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
......@@ -1050,13 +1049,8 @@ gl::Error Blit11::swizzleTexture(const gl::Context *context,
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
result =
deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map internal vertex buffer for swizzle, "
<< gl::FmtHR(result);
}
ANGLE_TRY(mRenderer->mapResource(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
&mappedResource));
ShaderSupport support;
ANGLE_TRY(getShaderSupport(*shader, &support));
......@@ -1072,12 +1066,8 @@ gl::Error Blit11::swizzleTexture(const gl::Context *context,
deviceContext->Unmap(mVertexBuffer.get(), 0);
// Set constant buffer
result = deviceContext->Map(mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map internal constant buffer for swizzle, "
<< gl::FmtHR(result);
}
ANGLE_TRY(
mRenderer->mapResource(mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
unsigned int *swizzleIndices = reinterpret_cast<unsigned int *>(mappedResource.pData);
swizzleIndices[0] = GetSwizzleIndex(swizzleTarget.swizzleRed);
......@@ -1139,7 +1129,6 @@ gl::Error Blit11::copyTexture(const gl::Context *context,
{
ANGLE_TRY(initResources());
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
// Determine if the source format is a signed integer format, the destFormat will already
......@@ -1165,13 +1154,8 @@ gl::Error Blit11::copyTexture(const gl::Context *context,
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
result =
deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, "
<< gl::FmtHR(result);
}
ANGLE_TRY(mRenderer->mapResource(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
&mappedResource));
UINT stride = 0;
UINT drawCount = 0;
......@@ -1269,18 +1253,12 @@ gl::Error Blit11::copyDepth(const gl::Context *context,
{
ANGLE_TRY(initResources());
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
result =
deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, "
<< gl::FmtHR(result);
}
ANGLE_TRY(mRenderer->mapResource(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
&mappedResource));
UINT stride = 0;
UINT drawCount = 0;
......@@ -1437,22 +1415,15 @@ gl::Error Blit11::copyAndConvertImpl(const TextureHelper11 &source,
sourceSubresource, nullptr);
D3D11_MAPPED_SUBRESOURCE sourceMapping;
HRESULT result = deviceContext->Map(sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping);
if (FAILED(result))
{
return gl::OutOfMemory()
<< "Failed to map internal source staging texture for depth stencil blit, "
<< gl::FmtHR(result);
}
ANGLE_TRY(mRenderer->mapResource(sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping));
D3D11_MAPPED_SUBRESOURCE destMapping;
result = deviceContext->Map(destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping);
if (FAILED(result))
gl::Error error =
mRenderer->mapResource(destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping);
if (error.isError())
{
deviceContext->Unmap(sourceStaging.get(), 0);
return gl::OutOfMemory()
<< "Failed to map internal destination staging texture for depth stencil blit, "
<< gl::FmtHR(result);
return error;
}
// Clip dest area to the destination size
......
......@@ -1195,16 +1195,10 @@ gl::Error Buffer11::NativeStorage::map(size_t offset,
ASSERT(isCPUAccessible(access));
D3D11_MAPPED_SUBRESOURCE mappedResource;
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(mUsage, access);
UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0);
HRESULT result = context->Map(mBuffer.get(), 0, d3dMapType, d3dMapFlag, &mappedResource);
ASSERT(SUCCEEDED(result));
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map native storage in Buffer11::NativeStorage::map";
}
ANGLE_TRY(mRenderer->mapResource(mBuffer.get(), 0, d3dMapType, d3dMapFlag, &mappedResource));
ASSERT(mappedResource.pData);
*mapPointerOut = static_cast<uint8_t *>(mappedResource.pData) + offset;
return gl::NoError();
......
......@@ -741,12 +741,8 @@ gl::Error Clear11::clearFramebuffer(const gl::Context *context,
// Update the constant buffer with the updated cache contents
// TODO(Shahmeer): Consider using UpdateSubresource1 D3D11_COPY_DISCARD where possible.
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result = deviceContext->Map(mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
&mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Clear11: Failed to map CB, " << gl::FmtHR(result);
}
ANGLE_TRY(mRenderer->mapResource(mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
&mappedResource));
memcpy(mappedResource.pData, &mShaderData, g_ConstantBufferSize);
deviceContext->Unmap(mConstantBuffer.get(), 0);
......
......@@ -625,20 +625,9 @@ gl::Error Image11::map(const gl::Context *context, D3D11_MAP mapType, D3D11_MAPP
unsigned int subresourceIndex = 0;
ANGLE_TRY(getStagingTexture(&stagingTexture, &subresourceIndex));
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
ASSERT(stagingTexture && stagingTexture->valid());
HRESULT result = deviceContext->Map(stagingTexture->get(), subresourceIndex, mapType, 0, map);
if (FAILED(result))
{
// this can fail if the device is removed (from TDR)
if (d3d11::isDeviceLostError(result))
{
mRenderer->notifyDeviceLost();
}
return gl::OutOfMemory() << "Failed to map staging texture, " << gl::FmtHR(result);
}
ANGLE_TRY(mRenderer->mapResource(stagingTexture->get(), subresourceIndex, mapType, 0, map));
mDirty = true;
......
......@@ -71,15 +71,9 @@ gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void*
return gl::OutOfMemory() << "Index buffer map range is not inside the buffer.";
}
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result =
dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result);
}
ANGLE_TRY(
mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource));
*outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
return gl::NoError();
......@@ -129,11 +123,8 @@ gl::Error IndexBuffer11::discard()
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result = dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result);
}
ANGLE_TRY(
mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
dxContext->Unmap(mBuffer.get(), 0);
......
......@@ -3298,12 +3298,7 @@ gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper,
ID3D11Resource *readResource = textureHelper.get();
D3D11_MAPPED_SUBRESOURCE mapping;
HRESULT hr = mDeviceContext->Map(readResource, 0, D3D11_MAP_READ, 0, &mapping);
if (FAILED(hr))
{
ASSERT(hr == E_OUTOFMEMORY);
return gl::OutOfMemory() << "Failed to map internal texture for reading, " << gl::FmtHR(hr);
}
ANGLE_TRY(mapResource(readResource, 0, D3D11_MAP_READ, 0, &mapping));
uint8_t *source = static_cast<uint8_t *>(mapping.pData);
int inputPitch = static_cast<int>(mapping.RowPitch);
......@@ -4032,6 +4027,35 @@ bool Renderer11::canSelectViewInVertexShader() const
getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader;
}
gl::Error Renderer11::mapResource(ID3D11Resource *resource,
UINT subResource,
D3D11_MAP mapType,
UINT mapFlags,
D3D11_MAPPED_SUBRESOURCE *mappedResource)
{
HRESULT hr = mDeviceContext->Map(resource, subResource, mapType, mapFlags, mappedResource);
if (FAILED(hr))
{
if (d3d11::isDeviceLostError(hr))
{
this->notifyDeviceLost();
}
const std::string genericFailureMessage = "Failed to map D3D11 resource.";
gl::Error glError = gl::InternalError() << genericFailureMessage << gl::FmtHR(hr);
if (E_OUTOFMEMORY)
{
glError = gl::OutOfMemory() << genericFailureMessage << gl::FmtHR(hr);
}
return glError;
}
return gl::NoError();
}
gl::Error Renderer11::markTransformFeedbackUsage(const gl::Context *context)
{
const gl::State &glState = context->getGLState();
......
......@@ -461,6 +461,12 @@ class Renderer11 : public RendererD3D
void onDirtyUniformBlockBinding(GLuint uniformBlockIndex) override;
gl::Error mapResource(ID3D11Resource *resource,
UINT subResource,
D3D11_MAP mapType,
UINT mapFlags,
D3D11_MAPPED_SUBRESOURCE *mappedResource);
private:
void generateCaps(gl::Caps *outCaps,
gl::TextureCapsMap *outTextureCaps,
......
......@@ -462,7 +462,7 @@ void ShaderConstants11::onSamplerChange(gl::ShaderType shaderType,
}
}
gl::Error ShaderConstants11::updateBuffer(ID3D11DeviceContext *deviceContext,
gl::Error ShaderConstants11::updateBuffer(Renderer11 *renderer,
gl::ShaderType shaderType,
const ProgramD3D &programD3D,
const d3d11::Buffer &driverConstantBuffer)
......@@ -512,20 +512,15 @@ gl::Error ShaderConstants11::updateBuffer(ID3D11DeviceContext *deviceContext,
// Previous buffer contents are discarded, so we need to refresh the whole buffer.
D3D11_MAPPED_SUBRESOURCE mapping = {0};
HRESULT result =
deviceContext->Map(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping);
if (FAILED(result))
{
return gl::OutOfMemory() << "Internal error mapping constant buffer: " << gl::FmtHR(result);
}
ANGLE_TRY(
renderer->mapResource(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping));
size_t samplerDataBytes = sizeof(SamplerMetadata) * programD3D.getUsedSamplerRange(shaderType);
memcpy(mapping.pData, data, dataSize);
memcpy(reinterpret_cast<uint8_t *>(mapping.pData) + dataSize, samplerData, samplerDataBytes);
deviceContext->Unmap(driverConstantBuffer.get(), 0);
renderer->getDeviceContext()->Unmap(driverConstantBuffer.get(), 0);
return gl::NoError();
}
......@@ -2788,9 +2783,9 @@ gl::Error StateManager11::applyDriverUniforms(const ProgramD3D &programD3D)
// Sampler metadata and driver constants need to coexist in the same constant buffer to conserve
// constant buffer slots. We update both in the constant buffer if needed.
ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SHADER_VERTEX, programD3D,
ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_VERTEX, programD3D,
mDriverConstantBufferVS));
ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SHADER_FRAGMENT, programD3D,
ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_FRAGMENT, programD3D,
mDriverConstantBufferPS));
// needed for the point sprite geometry shader
......@@ -2845,7 +2840,7 @@ gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D)
&buffer);
}
ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SHADER_COMPUTE, *programD3D,
ANGLE_TRY(mShaderConstants.updateBuffer(mRenderer, gl::SHADER_COMPUTE, *programD3D,
mDriverConstantBufferCS));
return gl::NoError();
......
......@@ -47,7 +47,7 @@ class ShaderConstants11 : angle::NonCopyable
unsigned int samplerIndex,
const gl::Texture &texture);
gl::Error updateBuffer(ID3D11DeviceContext *deviceContext,
gl::Error updateBuffer(Renderer11 *renderer,
gl::ShaderType shaderType,
const ProgramD3D &programD3D,
const d3d11::Buffer &driverConstantBuffer);
......
......@@ -70,17 +70,10 @@ gl::Error VertexBuffer11::mapResource()
{
if (mMappedResourceData == nullptr)
{
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result =
dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory()
<< "Failed to map internal vertex buffer, " << gl::FmtHR(result);
}
ANGLE_TRY(mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0,
&mappedResource));
mMappedResourceData = reinterpret_cast<uint8_t *>(mappedResource.pData);
}
......@@ -161,17 +154,11 @@ gl::Error VertexBuffer11::discard()
return gl::OutOfMemory() << "Internal vertex buffer is not initialized.";
}
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result = dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
return gl::OutOfMemory() << "Failed to map internal buffer for discarding, "
<< gl::FmtHR(result);
}
ANGLE_TRY(
mRenderer->mapResource(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
dxContext->Unmap(mBuffer.get(), 0);
mRenderer->getDeviceContext()->Unmap(mBuffer.get(), 0);
return gl::NoError();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment