Fix another bug introduced by r6301: Using observer variables now to check for ring buffer wraps.

Small performance improvements by increasing the ring buffer size and using a better offset algorithm.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6303 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
NeoBrainX 2010-10-23 09:59:33 +00:00
parent ae07f24b98
commit 5ebc9c97db
1 changed files with 33 additions and 22 deletions

View File

@ -15,6 +15,7 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include <list>
#include "Common.h" #include "Common.h"
#include "D3DBase.h" #include "D3DBase.h"
@ -28,8 +29,6 @@
namespace D3D namespace D3D
{ {
// TODO: Optimize the structures used by the Utils for size
// Ring buffer class, shared between the draw* functions // Ring buffer class, shared between the draw* functions
class UtilVertexBuffer class UtilVertexBuffer
{ {
@ -50,14 +49,18 @@ public:
D3D11_MAPPED_SUBRESOURCE map; D3D11_MAPPED_SUBRESOURCE map;
if(offset + size >= max_size) if(offset + size >= max_size)
{ {
context->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); // wrap buffer around and notify observers
offset = 0; offset = 0;
context->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
for(std::list<bool*>::iterator it = observers.begin(); it != observers.end(); ++it)
**it = true;
} }
else else
{ {
context->Map(buf, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); context->Map(buf, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
} }
offset += vertex_size - (offset % vertex_size); offset = ((offset+vertex_size-1)/vertex_size)*vertex_size; // align offset to vertex_size bytes
memcpy((u8*)map.pData + offset, data, size); memcpy((u8*)map.pData + offset, data, size);
context->Unmap(buf, 0); context->Unmap(buf, 0);
@ -65,16 +68,19 @@ public:
return (offset - size) / vertex_size; return (offset - size) / vertex_size;
} }
// Used to make sure we aren't using any invalid data void AddWrapObserver(bool* observer)
inline bool IsValidOffset(int off) { return (offset > off); } {
observers.push_back(observer);
}
inline ID3D11Buffer* &GetBuffer() { return buf; } inline ID3D11Buffer* &GetBuffer() { return buf; }
inline int GetSize() { return max_size; }
private: private:
ID3D11Buffer* buf; ID3D11Buffer* buf;
int offset; int offset;
int max_size; int max_size;
std::list<bool*> observers;
}; };
CD3DFont font; CD3DFont font;
@ -472,14 +478,15 @@ struct
float z; float z;
} clear_quad_data; } clear_quad_data;
int stq_offset; // ring buffer offsets
int stsq_offset; int stq_offset, stsq_offset, cq_offset, clearq_offset;
int cq_offset;
int clearq_offset; // observer variables for ring buffer wraps
bool stq_observer, stsq_observer, cq_observer, clearq_observer;
void InitUtils() void InitUtils()
{ {
util_vbuf = new UtilVertexBuffer(0x600); util_vbuf = new UtilVertexBuffer(0x4000);
float border[4] = { 0.f, 0.f, 0.f, 0.f }; float border[4] = { 0.f, 0.f, 0.f, 0.f };
D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX); D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
@ -498,11 +505,12 @@ void InitUtils()
memset(&draw_quad_data, 0, sizeof(draw_quad_data)); memset(&draw_quad_data, 0, sizeof(draw_quad_data));
memset(&clear_quad_data, 0, sizeof(clear_quad_data)); memset(&clear_quad_data, 0, sizeof(clear_quad_data));
// make sure these always point to invalid regions at the first call // make sure to properly load the vertex data whenever the corresponding functions get called the first time
stq_offset = util_vbuf->GetSize(); stq_observer = stsq_observer = cq_observer = clearq_observer = true;
stsq_offset = util_vbuf->GetSize(); util_vbuf->AddWrapObserver(&stq_observer);
cq_offset = util_vbuf->GetSize(); util_vbuf->AddWrapObserver(&stsq_observer);
clearq_offset = util_vbuf->GetSize(); util_vbuf->AddWrapObserver(&cq_observer);
util_vbuf->AddWrapObserver(&clearq_observer);
font.Init(); font.Init();
} }
@ -548,11 +556,12 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
}; };
// only upload the data to VRAM if it changed // only upload the data to VRAM if it changed
if (!util_vbuf->IsValidOffset(stq_offset) || if (stq_observer ||
tex_quad_data.u1 != u1 || tex_quad_data.v1 != v1 || tex_quad_data.u1 != u1 || tex_quad_data.v1 != v1 ||
tex_quad_data.u2 != u2 || tex_quad_data.v2 != v2) tex_quad_data.u2 != u2 || tex_quad_data.v2 != v2)
{ {
stq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STQVertex)); stq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STQVertex));
stq_observer = false;
tex_quad_data.u1 = u1; tex_quad_data.u1 = u1;
tex_quad_data.v1 = v1; tex_quad_data.v1 = v1;
@ -599,12 +608,13 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
}; };
// only upload the data to VRAM if it changed // only upload the data to VRAM if it changed
if (!util_vbuf->IsValidOffset(stsq_offset) || if (stsq_observer ||
memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(rDest)) != 0 || memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(rDest)) != 0 ||
tex_sub_quad_data.u1 != u1 || tex_sub_quad_data.v1 != v1 || tex_sub_quad_data.u1 != u1 || tex_sub_quad_data.v1 != v1 ||
tex_sub_quad_data.u2 != u2 || tex_sub_quad_data.v2 != v2) tex_sub_quad_data.u2 != u2 || tex_sub_quad_data.v2 != v2)
{ {
stsq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STSQVertex)); stsq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STSQVertex));
stsq_observer = false;
tex_sub_quad_data.u1 = u1; tex_sub_quad_data.u1 = u1;
tex_sub_quad_data.v1 = v1; tex_sub_quad_data.v1 = v1;
@ -639,12 +649,13 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
{ x2, y1, 0.f, Color }, { x2, y1, 0.f, Color },
}; };
if(!util_vbuf->IsValidOffset(cq_offset) || if(cq_observer ||
draw_quad_data.x1 != x1 || draw_quad_data.y1 != y1 || draw_quad_data.x1 != x1 || draw_quad_data.y1 != y1 ||
draw_quad_data.x2 != x2 || draw_quad_data.y2 != y2 || draw_quad_data.x2 != x2 || draw_quad_data.y2 != y2 ||
draw_quad_data.col != Color) draw_quad_data.col != Color)
{ {
cq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(ColVertex)); cq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(ColVertex));
cq_observer = false;
draw_quad_data.x1 = x1; draw_quad_data.x1 = x1;
draw_quad_data.y1 = y1; draw_quad_data.y1 = y1;
@ -674,10 +685,10 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS
{ 1.0f, -1.0f, z, Color}, { 1.0f, -1.0f, z, Color},
}; };
if (!util_vbuf->IsValidOffset(clearq_offset) || if (clearq_observer || clear_quad_data.col != Color || clear_quad_data.z != z)
clear_quad_data.col != Color || clear_quad_data.z != z)
{ {
clearq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(ClearVertex)); clearq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(ClearVertex));
clearq_observer = false;
clear_quad_data.col = Color; clear_quad_data.col = Color;
clear_quad_data.z = z; clear_quad_data.z = z;