mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
D3D11: Check Map() results
Map fails after device removal, leaving pData garbage. Skip the upload or draw instead of writing through it. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
bc581349fd
commit
ba37f327b0
3 files changed
+34
-8
No files matched your search
+13
-2
@@ -46,7 +46,11 @@ public:
|
||||
nextMapDiscard_ = true;
|
||||
}
|
||||
|
||||
// Returns null if the buffer can't be mapped (after device removal, for example). Skip the draw then.
|
||||
uint8_t *BeginPush(ID3D11DeviceContext *context, UINT *offset, size_t size, int align = 16) {
|
||||
if (!buffer_) {
|
||||
return nullptr;
|
||||
}
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
pos_ = (pos_ + align - 1) & ~(align - 1);
|
||||
if (pos_ + size > size_) {
|
||||
@@ -55,7 +59,10 @@ public:
|
||||
pos_ = 0;
|
||||
nextMapDiscard_ = true;
|
||||
}
|
||||
context->Map(buffer_.Get(), 0, nextMapDiscard_ ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
|
||||
if (FAILED(context->Map(buffer_.Get(), 0, nextMapDiscard_ ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map))) {
|
||||
return nullptr;
|
||||
}
|
||||
mapped_ = true;
|
||||
nextMapDiscard_ = false;
|
||||
*offset = (UINT)pos_;
|
||||
uint8_t *retval = (uint8_t *)map.pData + pos_;
|
||||
@@ -63,7 +70,10 @@ public:
|
||||
return retval;
|
||||
}
|
||||
void EndPush(ID3D11DeviceContext *context) {
|
||||
context->Unmap(buffer_.Get(), 0);
|
||||
if (mapped_) {
|
||||
context->Unmap(buffer_.Get(), 0);
|
||||
mapped_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -71,6 +81,7 @@ private:
|
||||
size_t pos_ = 0;
|
||||
size_t size_;
|
||||
bool nextMapDiscard_ = false;
|
||||
bool mapped_ = false;
|
||||
};
|
||||
|
||||
std::vector<uint8_t> CompileShaderToBytecodeD3D11(const char *code, size_t codeSize, const char *target, UINT flags, std::string *errorMessage = nullptr);
|
||||
|
||||
@@ -358,6 +358,9 @@ void DrawEngineD3D11::Flush() {
|
||||
UINT vOffset;
|
||||
int vSize = numDecodedVerts_ * dec_->GetDecVtxFmt().stride;
|
||||
uint8_t *vptr = pushVerts_->BeginPush(context_, &vOffset, vSize);
|
||||
if (!vptr) {
|
||||
goto bail;
|
||||
}
|
||||
memcpy(vptr, decoded_, vSize);
|
||||
pushVerts_->EndPush(context_);
|
||||
ID3D11Buffer *buf = pushVerts_->Buf();
|
||||
@@ -366,6 +369,9 @@ void DrawEngineD3D11::Flush() {
|
||||
UINT iOffset;
|
||||
int iSize = 2 * vertexCount;
|
||||
uint8_t *iptr = pushInds_->BeginPush(context_, &iOffset, iSize);
|
||||
if (!iptr) {
|
||||
goto bail;
|
||||
}
|
||||
memcpy(iptr, decIndex_, iSize);
|
||||
pushInds_->EndPush(context_);
|
||||
context_->IASetIndexBuffer(pushInds_->Buf(), DXGI_FORMAT_R16_UINT, iOffset);
|
||||
@@ -477,6 +483,9 @@ void DrawEngineD3D11::Flush() {
|
||||
UINT vOffset = 0;
|
||||
int vSize = result.drawVertexCount * stride;
|
||||
uint8_t *vptr = pushVerts_->BeginPush(context_, &vOffset, vSize);
|
||||
if (!vptr) {
|
||||
goto bail;
|
||||
}
|
||||
memcpy(vptr, result.drawBuffer, vSize);
|
||||
pushVerts_->EndPush(context_);
|
||||
ID3D11Buffer *buf = pushVerts_->Buf();
|
||||
@@ -484,6 +493,9 @@ void DrawEngineD3D11::Flush() {
|
||||
UINT iOffset;
|
||||
int iSize = sizeof(uint16_t) * result.drawIndexCount;
|
||||
uint8_t *iptr = pushInds_->BeginPush(context_, &iOffset, iSize);
|
||||
if (!iptr) {
|
||||
goto bail;
|
||||
}
|
||||
memcpy(iptr, inds, iSize);
|
||||
pushInds_->EndPush(context_);
|
||||
context_->IASetIndexBuffer(pushInds_->Buf(), DXGI_FORMAT_R16_UINT, iOffset);
|
||||
|
||||
@@ -147,15 +147,18 @@ uint64_t ShaderManagerD3D11::UpdateUniforms(bool useBufferedRendering, bool pixe
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
if (dirty & DIRTY_BASE_UNIFORMS) {
|
||||
BaseUpdateUniforms(&ub_base, dirty, useBufferedRendering, pixelMapped);
|
||||
context_->Map(push_base.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
memcpy(map.pData, &ub_base, sizeof(ub_base));
|
||||
context_->Unmap(push_base.Get(), 0);
|
||||
// Map fails after device removal, and map.pData is garbage then.
|
||||
if (SUCCEEDED(context_->Map(push_base.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map))) {
|
||||
memcpy(map.pData, &ub_base, sizeof(ub_base));
|
||||
context_->Unmap(push_base.Get(), 0);
|
||||
}
|
||||
}
|
||||
if (dirty & DIRTY_LIGHT_UNIFORMS) {
|
||||
LightUpdateUniforms(&ub_lights, dirty);
|
||||
context_->Map(push_lights.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
memcpy(map.pData, &ub_lights, sizeof(ub_lights));
|
||||
context_->Unmap(push_lights.Get(), 0);
|
||||
if (SUCCEEDED(context_->Map(push_lights.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map))) {
|
||||
memcpy(map.pData, &ub_lights, sizeof(ub_lights));
|
||||
context_->Unmap(push_lights.Get(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
gstate_c.CleanUniforms();
|
||||
|
||||
Reference in new issue
Block a user