Merge branch 'Graphic_Update' into GLSL-master

Conflicts:
	Source/Core/VideoCommon/Src/VertexManagerBase.cpp
	Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp
	Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
	Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
This commit is contained in:
degasus 2013-01-14 21:36:31 +01:00
commit 2f78986e2c
20 changed files with 691 additions and 546 deletions

View File

@ -23,7 +23,7 @@
int GetLightingShaderId(u32* out) int GetLightingShaderId(u32* out)
{ {
for (int i = 0; i < xfregs.numChan.numColorChans; ++i) for (u32 i = 0; i < xfregs.numChan.numColorChans; ++i)
{ {
out[i] = xfregs.color[i].enablelighting ? out[i] = xfregs.color[i].enablelighting ?
(u32)xfregs.color[i].hex : (u32)xfregs.color[i].hex :

View File

@ -102,7 +102,7 @@ public:
virtual void SetupVertexPointers() = 0; virtual void SetupVertexPointers() = 0;
virtual void EnableComponents(u32 components) {} virtual void EnableComponents(u32 components) {}
int GetVertexStride() const { return vertex_stride; } u32 GetVertexStride() const { return vertex_stride; }
// TODO: move this under private: // TODO: move this under private:
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present. u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.

View File

@ -346,7 +346,7 @@ static void Decode()
// Display lists get added directly into the FIFO stream // Display lists get added directly into the FIFO stream
if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL) if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL)
FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, g_pVideoData - opcodeStart); FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, u32(g_pVideoData - opcodeStart));
} }
static void DecodeSemiNop() static void DecodeSemiNop()
@ -429,7 +429,7 @@ static void DecodeSemiNop()
} }
if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL) if (g_bRecordFifoData && cmd_byte != GX_CMD_CALL_DL)
FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, g_pVideoData - opcodeStart); FifoRecorder::GetInstance().WriteGPCommand(opcodeStart, u32(g_pVideoData - opcodeStart));
} }
void OpcodeDecoder_Init() void OpcodeDecoder_Init()

View File

@ -192,7 +192,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
*ptr++ = components; *ptr++ = components;
} }
uid->num_values = ptr - uid->values; uid->num_values = int(ptr - uid->values);
} }
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components) void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components)
@ -225,7 +225,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u
*ptr++ = bpmem.tevindref.hex; // 32 *ptr++ = bpmem.tevindref.hex; // 32
for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times for (u32 i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times
{ {
*ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i *ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i
*ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i *ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i

View File

@ -163,6 +163,9 @@ void VertexManager::Flush()
// loading a state will invalidate BP, so check for it // loading a state will invalidate BP, so check for it
g_video_backend->CheckInvalidState(); g_video_backend->CheckInvalidState();
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed = true;
g_vertex_manager->vFlush(); g_vertex_manager->vFlush();
} }

View File

@ -41,39 +41,39 @@ namespace DX11
// TODO: Find sensible values for these two // TODO: Find sensible values for these two
const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16); const UINT IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16);
const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; const UINT VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
const UINT MAXVBUFFER_COUNT = 2; const UINT MAX_VBUFFER_COUNT = 2;
void VertexManager::CreateDeviceObjects() void VertexManager::CreateDeviceObjects()
{ {
D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE, D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(IBUFFER_SIZE,
D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
m_vertexDrawOffset = 0; m_vertex_draw_offset = 0;
m_triangleDrawIndex = 0; m_triangle_draw_index = 0;
m_lineDrawIndex = 0; m_line_draw_index = 0;
m_pointDrawIndex = 0; m_point_draw_index = 0;
m_indexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; m_index_buffers = new PID3D11Buffer[MAX_VBUFFER_COUNT];
m_vertexBuffers = new PID3D11Buffer[MAXVBUFFER_COUNT]; m_vertex_buffers = new PID3D11Buffer[MAX_VBUFFER_COUNT];
for (m_activeIndexBuffer = 0; m_activeIndexBuffer < MAXVBUFFER_COUNT; m_activeIndexBuffer++) for (m_current_index_buffer = 0; m_current_index_buffer < MAX_VBUFFER_COUNT; m_current_index_buffer++)
{ {
m_indexBuffers[m_activeIndexBuffer] = NULL; m_index_buffers[m_current_index_buffer] = NULL;
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_indexBuffers[m_activeIndexBuffer])), CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_index_buffers[m_current_index_buffer])),
"Failed to create index buffer."); "Failed to create index buffer.");
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_indexBuffers[m_activeIndexBuffer], "index buffer of VertexManager"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_index_buffers[m_current_index_buffer], "index buffer of VertexManager");
} }
bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufdesc.ByteWidth = VBUFFER_SIZE; bufdesc.ByteWidth = VBUFFER_SIZE;
for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++)
{ {
m_vertexBuffers[m_activeVertexBuffer] = NULL; m_vertex_buffers[m_current_vertex_buffer] = NULL;
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertexBuffers[m_activeVertexBuffer])), CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, &m_vertex_buffers[m_current_vertex_buffer])),
"Failed to create vertex buffer."); "Failed to create vertex buffer.");
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertexBuffers[m_activeVertexBuffer], "Vertex buffer of VertexManager"); D3D::SetDebugObjectName((ID3D11DeviceChild*)m_vertex_buffers[m_current_vertex_buffer], "Vertex buffer of VertexManager");
} }
m_activeVertexBuffer = 0; m_current_vertex_buffer = 0;
m_activeIndexBuffer = 0; m_current_index_buffer = 0;
m_indexBufferCursor = IBUFFER_SIZE; m_index_buffer_cursor = IBUFFER_SIZE;
m_vertexBufferCursor = VBUFFER_SIZE; m_vertex_buffer_cursor = VBUFFER_SIZE;
m_lineShader.Init(); m_lineShader.Init();
m_pointShader.Init(); m_pointShader.Init();
} }
@ -82,10 +82,10 @@ void VertexManager::DestroyDeviceObjects()
{ {
m_pointShader.Shutdown(); m_pointShader.Shutdown();
m_lineShader.Shutdown(); m_lineShader.Shutdown();
for (m_activeVertexBuffer = 0; m_activeVertexBuffer < MAXVBUFFER_COUNT; m_activeVertexBuffer++) for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++)
{ {
SAFE_RELEASE(m_vertexBuffers[m_activeVertexBuffer]); SAFE_RELEASE(m_vertex_buffers[m_current_vertex_buffer]);
SAFE_RELEASE(m_indexBuffers[m_activeVertexBuffer]); SAFE_RELEASE(m_index_buffers[m_current_vertex_buffer]);
} }
} }
@ -100,47 +100,47 @@ VertexManager::~VertexManager()
DestroyDeviceObjects(); DestroyDeviceObjects();
} }
void VertexManager::LoadBuffers() void VertexManager::PrepareDrawBuffers()
{ {
D3D11_MAPPED_SUBRESOURCE map; D3D11_MAPPED_SUBRESOURCE map;
UINT vSize = UINT(s_pCurBufferPointer - LocalVBuffer); UINT vSize = UINT(s_pCurBufferPointer - LocalVBuffer);
D3D11_MAP MapType = D3D11_MAP_WRITE_NO_OVERWRITE; D3D11_MAP MapType = D3D11_MAP_WRITE_NO_OVERWRITE;
if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE) if (m_vertex_buffer_cursor + vSize >= VBUFFER_SIZE)
{ {
// Wrap around // Wrap around
m_activeVertexBuffer = (m_activeVertexBuffer + 1) % MAXVBUFFER_COUNT; m_current_vertex_buffer = (m_current_vertex_buffer + 1) % MAX_VBUFFER_COUNT;
m_vertexBufferCursor = 0; m_vertex_buffer_cursor = 0;
MapType = D3D11_MAP_WRITE_DISCARD; MapType = D3D11_MAP_WRITE_DISCARD;
} }
D3D::context->Map(m_vertexBuffers[m_activeVertexBuffer], 0, MapType, 0, &map); D3D::context->Map(m_vertex_buffers[m_current_vertex_buffer], 0, MapType, 0, &map);
memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize); memcpy((u8*)map.pData + m_vertex_buffer_cursor, LocalVBuffer, vSize);
D3D::context->Unmap(m_vertexBuffers[m_activeVertexBuffer], 0); D3D::context->Unmap(m_vertex_buffers[m_current_vertex_buffer], 0);
m_vertexDrawOffset = m_vertexBufferCursor; m_vertex_draw_offset = m_vertex_buffer_cursor;
m_vertexBufferCursor += vSize; m_vertex_buffer_cursor += vSize;
UINT iCount = IndexGenerator::GetTriangleindexLen() + UINT iCount = IndexGenerator::GetTriangleindexLen() +
IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen();
MapType = D3D11_MAP_WRITE_NO_OVERWRITE; MapType = D3D11_MAP_WRITE_NO_OVERWRITE;
if (m_indexBufferCursor + iCount >= (IBUFFER_SIZE / sizeof(u16))) if (m_index_buffer_cursor + iCount >= (IBUFFER_SIZE / sizeof(u16)))
{ {
// Wrap around // Wrap around
m_activeIndexBuffer = (m_activeIndexBuffer + 1) % MAXVBUFFER_COUNT; m_current_index_buffer = (m_current_index_buffer + 1) % MAX_VBUFFER_COUNT;
m_indexBufferCursor = 0; m_index_buffer_cursor = 0;
MapType = D3D11_MAP_WRITE_DISCARD; MapType = D3D11_MAP_WRITE_DISCARD;
} }
D3D::context->Map(m_indexBuffers[m_activeIndexBuffer], 0, MapType, 0, &map); D3D::context->Map(m_index_buffers[m_current_index_buffer], 0, MapType, 0, &map);
m_triangleDrawIndex = m_indexBufferCursor; m_triangle_draw_index = m_index_buffer_cursor;
m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen(); m_line_draw_index = m_triangle_draw_index + IndexGenerator::GetTriangleindexLen();
m_pointDrawIndex = m_lineDrawIndex + IndexGenerator::GetLineindexLen(); m_point_draw_index = m_line_draw_index + IndexGenerator::GetLineindexLen();
memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, sizeof(u16) * IndexGenerator::GetTriangleindexLen()); memcpy((u16*)map.pData + m_triangle_draw_index, TIBuffer, sizeof(u16) * IndexGenerator::GetTriangleindexLen());
memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen()); memcpy((u16*)map.pData + m_line_draw_index, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen());
memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen()); memcpy((u16*)map.pData + m_point_draw_index, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen());
D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0); D3D::context->Unmap(m_index_buffers[m_current_index_buffer], 0);
m_indexBufferCursor += iCount; m_index_buffer_cursor += iCount;
} }
static const float LINE_PT_TEX_OFFSETS[8] = { static const float LINE_PT_TEX_OFFSETS[8] = {
@ -149,13 +149,13 @@ static const float LINE_PT_TEX_OFFSETS[8] = {
void VertexManager::Draw(UINT stride) void VertexManager::Draw(UINT stride)
{ {
D3D::context->IASetVertexBuffers(0, 1, &m_vertexBuffers[m_activeVertexBuffer], &stride, &m_vertexDrawOffset); D3D::context->IASetVertexBuffers(0, 1, &m_vertex_buffers[m_current_vertex_buffer], &stride, &m_vertex_draw_offset);
D3D::context->IASetIndexBuffer(m_indexBuffers[m_activeIndexBuffer], DXGI_FORMAT_R16_UINT, 0); D3D::context->IASetIndexBuffer(m_index_buffers[m_current_index_buffer], DXGI_FORMAT_R16_UINT, 0);
if (IndexGenerator::GetNumTriangles() > 0) if (IndexGenerator::GetNumTriangles() > 0)
{ {
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangleDrawIndex, 0); D3D::context->DrawIndexed(IndexGenerator::GetTriangleindexLen(), m_triangle_draw_index, 0);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
// Disable culling for lines and points // Disable culling for lines and points
@ -177,7 +177,7 @@ void VertexManager::Draw(UINT stride)
texOffset, vpWidth, vpHeight, texOffsetEnable)) texOffset, vpWidth, vpHeight, texOffsetEnable))
{ {
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0); D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_line_draw_index, 0);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
D3D::context->GSSetShader(NULL, NULL, 0); D3D::context->GSSetShader(NULL, NULL, 0);
@ -199,7 +199,7 @@ void VertexManager::Draw(UINT stride)
texOffset, vpWidth, vpHeight, texOffsetEnable)) texOffset, vpWidth, vpHeight, texOffsetEnable))
{ {
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0); D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_point_draw_index, 0);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
D3D::context->GSSetShader(NULL, NULL, 0); D3D::context->GSSetShader(NULL, NULL, 0);
@ -211,9 +211,6 @@ void VertexManager::Draw(UINT stride)
void VertexManager::vFlush() void VertexManager::vFlush()
{ {
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed=true;
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
u32 usedtextures = 0; u32 usedtextures = 0;
@ -270,7 +267,7 @@ void VertexManager::vFlush()
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
goto shader_fail; goto shader_fail;
} }
LoadBuffers(); PrepareDrawBuffers();
unsigned int stride = g_nativeVertexFmt->GetVertexStride(); unsigned int stride = g_nativeVertexFmt->GetVertexStride();
g_nativeVertexFmt->SetupVertexPointers(); g_nativeVertexFmt->SetupVertexPointers();
g_renderer->ApplyState(useDstAlpha); g_renderer->ApplyState(useDstAlpha);

View File

@ -37,22 +37,22 @@ public:
private: private:
void LoadBuffers(); void PrepareDrawBuffers();
void Draw(UINT stride); void Draw(u32 stride);
// temp // temp
void vFlush(); void vFlush();
UINT m_indexBufferCursor; u32 m_vertex_buffer_cursor;
UINT m_vertexBufferCursor; u32 m_vertex_draw_offset;
UINT m_vertexDrawOffset; u32 m_index_buffer_cursor;
UINT m_triangleDrawIndex; u32 m_current_vertex_buffer;
UINT m_lineDrawIndex; u32 m_current_index_buffer;
UINT m_pointDrawIndex; u32 m_triangle_draw_index;
UINT m_activeVertexBuffer; u32 m_line_draw_index;
UINT m_activeIndexBuffer; u32 m_point_draw_index;
typedef ID3D11Buffer* PID3D11Buffer; typedef ID3D11Buffer* PID3D11Buffer;
PID3D11Buffer* m_indexBuffers; PID3D11Buffer* m_index_buffers;
PID3D11Buffer* m_vertexBuffers; PID3D11Buffer* m_vertex_buffers;
LineGeometryShader m_lineShader; LineGeometryShader m_lineShader;
PointGeometryShader m_pointShader; PointGeometryShader m_pointShader;

View File

@ -66,6 +66,7 @@ static int numAdapters;
static int cur_adapter; static int cur_adapter;
// Value caches for state filtering // Value caches for state filtering
const int MaxStreamSources = 16;
const int MaxTextureStages = 9; const int MaxTextureStages = 9;
const int MaxRenderStates = 210 + 46; const int MaxRenderStates = 210 + 46;
const int MaxTextureTypes = 33; const int MaxTextureTypes = 33;
@ -83,10 +84,23 @@ static DWORD m_SamplerStates[MaxSamplerSize][MaxSamplerTypes];
static bool m_SamplerStatesSet[MaxSamplerSize][MaxSamplerTypes]; static bool m_SamplerStatesSet[MaxSamplerSize][MaxSamplerTypes];
static bool m_SamplerStatesChanged[MaxSamplerSize][MaxSamplerTypes]; static bool m_SamplerStatesChanged[MaxSamplerSize][MaxSamplerTypes];
LPDIRECT3DBASETEXTURE9 m_Textures[16]; static LPDIRECT3DBASETEXTURE9 m_Textures[16];
LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl; static LPDIRECT3DVERTEXDECLARATION9 m_VtxDecl;
LPDIRECT3DPIXELSHADER9 m_PixelShader; static bool m_VtxDeclChanged;
LPDIRECT3DVERTEXSHADER9 m_VertexShader; static LPDIRECT3DPIXELSHADER9 m_PixelShader;
static bool m_PixelShaderChanged;
static LPDIRECT3DVERTEXSHADER9 m_VertexShader;
static bool m_VertexShaderChanged;
struct StreamSourceDescriptor
{
LPDIRECT3DVERTEXBUFFER9 pStreamData;
UINT OffsetInBytes;
UINT Stride;
};
static StreamSourceDescriptor m_stream_sources[MaxStreamSources];
static bool m_stream_sources_Changed[MaxStreamSources];
static LPDIRECT3DINDEXBUFFER9 m_index_buffer;
static bool m_index_buffer_Changed;
// Z buffer formats to be used for EFB depth surface // Z buffer formats to be used for EFB depth surface
D3DFORMAT DepthFormats[] = { D3DFORMAT DepthFormats[] = {
@ -170,9 +184,9 @@ void EnableAlphaToCoverage()
{ {
// Each vendor has their own specific little hack. // Each vendor has their own specific little hack.
if (GetCurAdapter().ident.VendorId == VENDOR_ATI) if (GetCurAdapter().ident.VendorId == VENDOR_ATI)
D3D::SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1')); SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1'));
else else
D3D::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')); SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
} }
void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp) void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp)
@ -215,14 +229,14 @@ void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp)
void Enumerate() void Enumerate()
{ {
numAdapters = D3D::D3D->GetAdapterCount(); numAdapters = D3D->GetAdapterCount();
for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++) for (int i = 0; i < std::min(MAX_ADAPTERS, numAdapters); i++)
{ {
Adapter &a = adapters[i]; Adapter &a = adapters[i];
a.aa_levels.clear(); a.aa_levels.clear();
a.resolutions.clear(); a.resolutions.clear();
D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident); D3D->GetAdapterIdentifier(i, 0, &a.ident);
bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA; bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA;
// Add SuperSamples modes // Add SuperSamples modes
@ -233,17 +247,17 @@ void Enumerate()
//disable them will they are not implemnted //disable them will they are not implemnted
/* /*
DWORD qlevels = 0; DWORD qlevels = 0;
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
if (qlevels > 0) if (qlevels > 0)
a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0)); a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0));
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
if (qlevels > 0) if (qlevels > 0)
a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0)); a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0));
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
if (qlevels > 0) if (qlevels > 0)
a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
@ -251,7 +265,7 @@ void Enumerate()
if (isNvidia) if (isNvidia)
{ {
// CSAA support // CSAA support
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels))
{ {
if (qlevels > 2) if (qlevels > 2)
@ -262,7 +276,7 @@ void Enumerate()
a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
} }
} }
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
{ {
if (qlevels > 2) if (qlevels > 2)
@ -296,11 +310,11 @@ void Enumerate()
{ {
strcpy(a.aa_levels[0].name, "(Not supported on this device)"); strcpy(a.aa_levels[0].name, "(Not supported on this device)");
} }
int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8); int numModes = D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8);
for (int m = 0; m < numModes; m++) for (int m = 0; m < numModes; m++)
{ {
D3DDISPLAYMODE mode; D3DDISPLAYMODE mode;
D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode); D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode);
int found = -1; int found = -1;
for (int x = 0; x < (int)a.resolutions.size(); x++) for (int x = 0; x < (int)a.resolutions.size(); x++)
@ -440,8 +454,8 @@ HRESULT Create(int adapter, HWND wnd, int _resolution, int aa_mode, bool auto_de
dev->GetRenderTarget(0, &back_buffer); dev->GetRenderTarget(0, &back_buffer);
if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND) if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
back_buffer_z = NULL; back_buffer_z = NULL;
D3D::SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE ); SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE );
D3D::SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); SetRenderState(D3DRS_FILLMODE, g_Config.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
memset(m_Textures, 0, sizeof(m_Textures)); memset(m_Textures, 0, sizeof(m_Textures));
memset(m_TextureStageStatesSet, 0, sizeof(m_TextureStageStatesSet)); memset(m_TextureStageStatesSet, 0, sizeof(m_TextureStageStatesSet));
memset(m_RenderStatesSet, 0, sizeof(m_RenderStatesSet)); memset(m_RenderStatesSet, 0, sizeof(m_RenderStatesSet));
@ -452,6 +466,15 @@ HRESULT Create(int adapter, HWND wnd, int _resolution, int aa_mode, bool auto_de
m_VtxDecl = NULL; m_VtxDecl = NULL;
m_PixelShader = NULL; m_PixelShader = NULL;
m_VertexShader = NULL; m_VertexShader = NULL;
m_index_buffer = NULL;
memset(m_stream_sources, 0, sizeof(m_stream_sources));
m_index_buffer = NULL;
m_VtxDeclChanged = false;
m_PixelShaderChanged = false;
m_VertexShaderChanged = false;
memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed));
m_index_buffer_Changed = false;
// Device state would normally be set here // Device state would normally be set here
return S_OK; return S_OK;
} }
@ -516,7 +539,7 @@ bool CheckDepthStencilSupport(D3DFORMAT target_format, D3DFORMAT depth_format)
D3DFORMAT GetSupportedDepthTextureFormat() D3DFORMAT GetSupportedDepthTextureFormat()
{ {
for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i) for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i)
if (D3D::CheckTextureSupport(D3DUSAGE_DEPTHSTENCIL, DepthFormats[i])) if (CheckTextureSupport(D3DUSAGE_DEPTHSTENCIL, DepthFormats[i]))
return DepthFormats[i]; return DepthFormats[i];
return D3DFMT_UNKNOWN; return D3DFMT_UNKNOWN;
@ -525,7 +548,7 @@ D3DFORMAT GetSupportedDepthTextureFormat()
D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format) D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format)
{ {
for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i) for (int i = 0; i < sizeof(DepthFormats)/sizeof(D3DFORMAT); ++i)
if (D3D::CheckDepthStencilSupport(target_format, DepthFormats[i])) if (CheckDepthStencilSupport(target_format, DepthFormats[i]))
return DepthFormats[i]; return DepthFormats[i];
return D3DFMT_UNKNOWN; return D3DFMT_UNKNOWN;
@ -533,13 +556,13 @@ D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format)
const char *VertexShaderVersionString() const char *VertexShaderVersionString()
{ {
int version = ((D3D::caps.VertexShaderVersion >> 8) & 0xFF); int version = ((caps.VertexShaderVersion >> 8) & 0xFF);
return vsVersions[std::min(4, version)]; return vsVersions[std::min(4, version)];
} }
const char *PixelShaderVersionString() const char *PixelShaderVersionString()
{ {
int version = ((D3D::caps.PixelShaderVersion >> 8) & 0xFF); int version = ((caps.PixelShaderVersion >> 8) & 0xFF);
return psVersions[std::min(4, version)]; return psVersions[std::min(4, version)];
} }
@ -653,14 +676,14 @@ void ApplyCachedState()
for (int type = 0; type < MaxSamplerTypes; type++) for (int type = 0; type < MaxSamplerTypes; type++)
{ {
if(m_SamplerStatesSet[sampler][type]) if(m_SamplerStatesSet[sampler][type])
D3D::dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]); dev->SetSamplerState(sampler, (D3DSAMPLERSTATETYPE)type, m_SamplerStates[sampler][type]);
} }
} }
for (int rs = 0; rs < MaxRenderStates; rs++) for (int rs = 0; rs < MaxRenderStates; rs++)
{ {
if (m_RenderStatesSet[rs]) if (m_RenderStatesSet[rs])
D3D::dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]); dev->SetRenderState((D3DRENDERSTATETYPE)rs, m_RenderStates[rs]);
} }
// We don't bother restoring these so let's just wipe the state copy // We don't bother restoring these so let's just wipe the state copy
@ -671,6 +694,13 @@ void ApplyCachedState()
m_VtxDecl = NULL; m_VtxDecl = NULL;
m_PixelShader = NULL; m_PixelShader = NULL;
m_VertexShader = NULL; m_VertexShader = NULL;
memset(m_stream_sources, 0, sizeof(m_stream_sources));
m_index_buffer = NULL;
m_VtxDeclChanged = false;
m_PixelShaderChanged = false;
m_VertexShaderChanged = false;
memset(m_stream_sources_Changed, 0 , sizeof(m_stream_sources_Changed));
m_index_buffer_Changed = false;
} }
void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture) void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
@ -678,7 +708,7 @@ void SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
if (m_Textures[Stage] != pTexture) if (m_Textures[Stage] != pTexture)
{ {
m_Textures[Stage] = pTexture; m_Textures[Stage] = pTexture;
D3D::dev->SetTexture(Stage, pTexture); dev->SetTexture(Stage, pTexture);
} }
} }
@ -686,7 +716,7 @@ void RefreshRenderState(D3DRENDERSTATETYPE State)
{ {
if(m_RenderStatesSet[State] && m_RenderStatesChanged[State]) if(m_RenderStatesSet[State] && m_RenderStatesChanged[State])
{ {
D3D::dev->SetRenderState(State, m_RenderStates[State]); dev->SetRenderState(State, m_RenderStates[State]);
m_RenderStatesChanged[State] = false; m_RenderStatesChanged[State] = false;
} }
} }
@ -698,7 +728,7 @@ void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
m_RenderStates[State] = Value; m_RenderStates[State] = Value;
m_RenderStatesSet[State] = true; m_RenderStatesSet[State] = true;
m_RenderStatesChanged[State] = false; m_RenderStatesChanged[State] = false;
D3D::dev->SetRenderState(State, Value); dev->SetRenderState(State, Value);
} }
} }
@ -707,7 +737,7 @@ void ChangeRenderState(D3DRENDERSTATETYPE State, DWORD Value)
if (m_RenderStates[State] != Value || !m_RenderStatesSet[State]) if (m_RenderStates[State] != Value || !m_RenderStatesSet[State])
{ {
m_RenderStatesChanged[State] = m_RenderStatesSet[State]; m_RenderStatesChanged[State] = m_RenderStatesSet[State];
D3D::dev->SetRenderState(State, Value); dev->SetRenderState(State, Value);
} }
else else
{ {
@ -722,7 +752,7 @@ void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Valu
m_TextureStageStates[Stage][Type] = Value; m_TextureStageStates[Stage][Type] = Value;
m_TextureStageStatesSet[Stage][Type]=true; m_TextureStageStatesSet[Stage][Type]=true;
m_TextureStageStatesChanged[Stage][Type]=false; m_TextureStageStatesChanged[Stage][Type]=false;
D3D::dev->SetTextureStageState(Stage, Type, Value); dev->SetTextureStageState(Stage, Type, Value);
} }
} }
@ -730,7 +760,7 @@ void RefreshTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type)
{ {
if(m_TextureStageStatesSet[Stage][Type] && m_TextureStageStatesChanged[Stage][Type]) if(m_TextureStageStatesSet[Stage][Type] && m_TextureStageStatesChanged[Stage][Type])
{ {
D3D::dev->SetTextureStageState(Stage, Type, m_TextureStageStates[Stage][Type]); dev->SetTextureStageState(Stage, Type, m_TextureStageStates[Stage][Type]);
m_TextureStageStatesChanged[Stage][Type] = false; m_TextureStageStatesChanged[Stage][Type] = false;
} }
} }
@ -740,7 +770,7 @@ void ChangeTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD V
if (m_TextureStageStates[Stage][Type] != Value || !m_TextureStageStatesSet[Stage][Type]) if (m_TextureStageStates[Stage][Type] != Value || !m_TextureStageStatesSet[Stage][Type])
{ {
m_TextureStageStatesChanged[Stage][Type] = m_TextureStageStatesSet[Stage][Type]; m_TextureStageStatesChanged[Stage][Type] = m_TextureStageStatesSet[Stage][Type];
D3D::dev->SetTextureStageState(Stage, Type, Value); dev->SetTextureStageState(Stage, Type, Value);
} }
else else
{ {
@ -755,7 +785,7 @@ void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
m_SamplerStates[Sampler][Type] = Value; m_SamplerStates[Sampler][Type] = Value;
m_SamplerStatesSet[Sampler][Type] = true; m_SamplerStatesSet[Sampler][Type] = true;
m_SamplerStatesChanged[Sampler][Type] = false; m_SamplerStatesChanged[Sampler][Type] = false;
D3D::dev->SetSamplerState(Sampler, Type, Value); dev->SetSamplerState(Sampler, Type, Value);
} }
} }
@ -763,7 +793,7 @@ void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type)
{ {
if(m_SamplerStatesSet[Sampler][Type] && m_SamplerStatesChanged[Sampler][Type]) if(m_SamplerStatesSet[Sampler][Type] && m_SamplerStatesChanged[Sampler][Type])
{ {
D3D::dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]); dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]);
m_SamplerStatesChanged[Sampler][Type] = false; m_SamplerStatesChanged[Sampler][Type] = false;
} }
} }
@ -773,7 +803,7 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
if (m_SamplerStates[Sampler][Type] != Value || !m_SamplerStatesSet[Sampler][Type]) if (m_SamplerStates[Sampler][Type] != Value || !m_SamplerStatesSet[Sampler][Type])
{ {
m_SamplerStatesChanged[Sampler][Type] = m_SamplerStatesSet[Sampler][Type]; m_SamplerStatesChanged[Sampler][Type] = m_SamplerStatesSet[Sampler][Type];
D3D::dev->SetSamplerState(Sampler, Type, Value); dev->SetSamplerState(Sampler, Type, Value);
} }
else else
{ {
@ -783,67 +813,155 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
void RefreshVertexDeclaration() void RefreshVertexDeclaration()
{ {
if (m_VtxDecl) if (m_VtxDeclChanged)
{ {
D3D::dev->SetVertexDeclaration(m_VtxDecl); dev->SetVertexDeclaration(m_VtxDecl);
m_VtxDeclChanged = false;
} }
} }
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl) void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl)
{ {
if (!decl) {
m_VtxDecl = NULL;
return;
}
if (decl != m_VtxDecl) if (decl != m_VtxDecl)
{ {
D3D::dev->SetVertexDeclaration(decl); dev->SetVertexDeclaration(decl);
m_VtxDecl = decl; m_VtxDecl = decl;
m_VtxDeclChanged = false;
}
}
void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl)
{
if (decl != m_VtxDecl) {
dev->SetVertexDeclaration(decl);
m_VtxDeclChanged = true;
}
}
void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader)
{
if (shader != m_VertexShader)
{
dev->SetVertexShader(shader);
m_VertexShaderChanged = true;
} }
} }
void RefreshVertexShader() void RefreshVertexShader()
{ {
if (m_VertexShader) if (m_VertexShaderChanged)
{ {
D3D::dev->SetVertexShader(m_VertexShader); dev->SetVertexShader(m_VertexShader);
m_VertexShaderChanged = false;
} }
} }
void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader) void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader)
{ {
if (!shader) {
m_VertexShader = NULL;
return;
}
if (shader != m_VertexShader) if (shader != m_VertexShader)
{ {
D3D::dev->SetVertexShader(shader); dev->SetVertexShader(shader);
m_VertexShader = shader; m_VertexShader = shader;
m_VertexShaderChanged = false;
} }
} }
void RefreshPixelShader() void RefreshPixelShader()
{ {
if (m_PixelShader) if (m_PixelShaderChanged)
{ {
D3D::dev->SetPixelShader(m_PixelShader); dev->SetPixelShader(m_PixelShader);
m_PixelShaderChanged = false;
} }
} }
void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader) void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader)
{ {
if (!shader) {
m_PixelShader = NULL;
return;
}
if (shader != m_PixelShader) if (shader != m_PixelShader)
{ {
D3D::dev->SetPixelShader(shader); dev->SetPixelShader(shader);
m_PixelShader = shader; m_PixelShader = shader;
m_PixelShaderChanged = false;
} }
} }
void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader)
{
if (shader != m_PixelShader)
{
dev->SetPixelShader(shader);
m_PixelShaderChanged = true;
}
}
void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride)
{
if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes
|| m_stream_sources[StreamNumber].pStreamData != pStreamData
|| m_stream_sources[StreamNumber].Stride != Stride)
{
m_stream_sources[StreamNumber].OffsetInBytes = OffsetInBytes;
m_stream_sources[StreamNumber].pStreamData = pStreamData;
m_stream_sources[StreamNumber].Stride = Stride;
dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride);
m_stream_sources_Changed[StreamNumber] = false;
}
}
void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride)
{
if (m_stream_sources[StreamNumber].OffsetInBytes != OffsetInBytes
|| m_stream_sources[StreamNumber].pStreamData != pStreamData
|| m_stream_sources[StreamNumber].Stride != Stride)
{
dev->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride);
m_stream_sources_Changed[StreamNumber] = true;
}
}
void RefreshStreamSource(UINT StreamNumber)
{
if (m_PixelShaderChanged)
{
dev->SetStreamSource(
StreamNumber,
m_stream_sources[StreamNumber].pStreamData,
m_stream_sources[StreamNumber].OffsetInBytes,
m_stream_sources[StreamNumber].Stride);
m_stream_sources_Changed[StreamNumber] = false;
}
}
void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData)
{
if(pIndexData != m_index_buffer)
{
m_index_buffer = pIndexData;
dev->SetIndices(pIndexData);
m_index_buffer_Changed = false;
}
}
void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData)
{
if(pIndexData != m_index_buffer)
{
dev->SetIndices(pIndexData);
m_index_buffer_Changed = true;
}
}
void RefreshIndices()
{
if (m_index_buffer_Changed)
{
dev->SetIndices(m_index_buffer);
m_index_buffer_Changed = false;
}
}
} // namespace } // namespace

View File

@ -100,12 +100,23 @@ void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
void RefreshVertexDeclaration(); void RefreshVertexDeclaration();
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl); void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
void ChangeVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
void RefreshVertexShader(); void RefreshVertexShader();
void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader); void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader);
void ChangeVertexShader(LPDIRECT3DVERTEXSHADER9 shader);
void RefreshPixelShader(); void RefreshPixelShader();
void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader); void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader);
void ChangePixelShader(LPDIRECT3DPIXELSHADER9 shader);
void SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
void ChangeStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
void RefreshStreamSource(UINT StreamNumber);
void SetIndices(LPDIRECT3DINDEXBUFFER9 pIndexData);
void ChangeIndices(LPDIRECT3DINDEXBUFFER9 pIndexData);
void RefreshIndices();
void ApplyCachedState(); void ApplyCachedState();

View File

@ -198,6 +198,8 @@ const int TS[6][2] =
void RestoreShaders() void RestoreShaders()
{ {
D3D::SetTexture(0, 0); D3D::SetTexture(0, 0);
D3D::RefreshStreamSource(0);
D3D::RefreshIndices();
D3D::RefreshVertexDeclaration(); D3D::RefreshVertexDeclaration();
D3D::RefreshPixelShader(); D3D::RefreshPixelShader();
D3D::RefreshVertexShader(); D3D::RefreshVertexShader();
@ -217,9 +219,9 @@ void CD3DFont::SetRenderStates()
{ {
D3D::SetTexture(0, m_pTexture); D3D::SetTexture(0, m_pTexture);
dev->SetPixelShader(0); D3D::ChangePixelShader(0);
dev->SetVertexShader(0); D3D::ChangeVertexShader(0);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_FONT2DVERTEX); dev->SetFVF(D3DFVF_FONT2DVERTEX);
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
@ -236,7 +238,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo
return 0; return 0;
SetRenderStates(); SetRenderStates();
dev->SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX)); D3D::ChangeStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX));
float vpWidth = 1; float vpWidth = 1;
float vpHeight = 1; float vpHeight = 1;
@ -389,9 +391,10 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
{ 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh, g}, { 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh, g},
{ 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh, g} { 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh, g}
}; };
dev->SetVertexShader(Vshader); D3D::ChangeVertexShader(Vshader);
dev->SetPixelShader(PShader); D3D::ChangePixelShader(PShader);
D3D::SetTexture(0, texture); D3D::SetTexture(0, texture);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2));
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
RestoreShaders(); RestoreShaders();
@ -424,9 +427,10 @@ void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
{ rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh, g}, { rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh, g},
{ rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh, g} { rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh, g}
}; };
dev->SetVertexShader(Vshader); D3D::ChangeVertexShader(Vshader);
dev->SetPixelShader(PShader); D3D::ChangePixelShader(PShader);
D3D::SetTexture(0, texture); D3D::SetTexture(0, texture);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2));
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
RestoreShaders(); RestoreShaders();
@ -442,8 +446,9 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
{ x1, y1, 0.f, 1.f, Color }, { x1, y1, 0.f, 1.f, Color },
{ x2, y1, 0.f, 1.f, Color }, { x2, y1, 0.f, 1.f, Color },
}; };
dev->SetVertexShader(VertexShaderCache::GetClearVertexShader()); D3D::ChangeVertexShader(VertexShaderCache::GetClearVertexShader());
dev->SetPixelShader(PixelShaderCache::GetClearProgram()); D3D::ChangePixelShader(PixelShaderCache::GetClearProgram());
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(CQVertex)); dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(CQVertex));
RestoreShaders(); RestoreShaders();
@ -457,8 +462,9 @@ void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVer
{ 1.0f, -1.0f, z, 1.0f, Color}, { 1.0f, -1.0f, z, 1.0f, Color},
{-1.0f, -1.0f, z, 1.0f, Color} {-1.0f, -1.0f, z, 1.0f, Color}
}; };
dev->SetVertexShader(Vshader); D3D::ChangeVertexShader(Vshader);
dev->SetPixelShader(PShader); D3D::ChangePixelShader(PShader);
D3D::ChangeVertexDeclaration(0);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE); dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex)); dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
RestoreShaders(); RestoreShaders();

View File

@ -67,6 +67,7 @@ static int s_fps = 0;
static u32 s_blendMode; static u32 s_blendMode;
static u32 s_LastAA; static u32 s_LastAA;
static bool IS_AMD; static bool IS_AMD;
static float m_fMaxPointSize;
static char *st; static char *st;
@ -329,6 +330,9 @@ Renderer::Renderer()
D3D::BeginFrame(); D3D::BeginFrame();
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false);
m_fMaxPointSize = D3D::GetCaps().MaxPointSize;
} }
Renderer::~Renderer() Renderer::~Renderer()
@ -1304,7 +1308,15 @@ void Renderer::SetLineWidth()
// We can't change line width in D3D unless we use ID3DXLine // We can't change line width in D3D unless we use ID3DXLine
float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f;
float psize = bpmem.lineptwidth.linesize * fratio / 6.0f; float psize = bpmem.lineptwidth.linesize * fratio / 6.0f;
//little hack to compensate scalling problems in dx9 must be taken out when scalling is fixed.
psize *= 2.0f;
if (psize > m_fMaxPointSize)
{
psize = m_fMaxPointSize;
}
D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize));
D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize));
D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize));
} }
void Renderer::SetSamplerState(int stage, int texindex) void Renderer::SetSamplerState(int stage, int texindex)

View File

@ -44,7 +44,7 @@ namespace DX9
//This are the initially requeted size for the buffers expresed in elements //This are the initially requeted size for the buffers expresed in elements
const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16; const u32 IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16;
const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16; const u32 VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
const u32 MAXVBUFFER_COUNT = 2; const u32 MAX_VBUFFER_COUNT = 2;
inline void DumpBadShaders() inline void DumpBadShaders()
{ {
@ -67,88 +67,88 @@ inline void DumpBadShaders()
void VertexManager::CreateDeviceObjects() void VertexManager::CreateDeviceObjects()
{ {
NumVBuffers = 0; m_buffers_count = 0;
VBuffers = NULL; m_vertex_buffers = NULL;
IBuffers = NULL; m_index_buffers = NULL;
D3DCAPS9 DeviceCaps = D3D::GetCaps(); D3DCAPS9 DeviceCaps = D3D::GetCaps();
u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride;
//Calculate Device Dependant size //Calculate Device Dependant size
CurrentVBufferSize = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE;
CurrentIBufferSize = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE;
//if device caps are not enough for Vbuffer fall back to vertex arrays //if device caps are not enough for Vbuffer fall back to vertex arrays
if (CurrentIBufferSize < MAXIBUFFERSIZE || CurrentVBufferSize < MAXVBUFFERSIZE) return; if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return;
VBuffers = new LPDIRECT3DVERTEXBUFFER9[MAXVBUFFER_COUNT]; m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT];
IBuffers = new LPDIRECT3DINDEXBUFFER9[MAXVBUFFER_COUNT]; m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT];
bool Fail = false; bool Fail = false;
for (CurrentVBuffer = 0; CurrentVBuffer < MAXVBUFFER_COUNT; CurrentVBuffer++) for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++)
{ {
VBuffers[CurrentVBuffer] = NULL; m_vertex_buffers[m_current_vertex_buffer] = NULL;
IBuffers[CurrentVBuffer] = NULL; m_index_buffers[m_current_vertex_buffer] = NULL;
} }
for (CurrentVBuffer = 0; CurrentVBuffer < MAXVBUFFER_COUNT; CurrentVBuffer++) for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++)
{ {
if(FAILED( D3D::dev->CreateVertexBuffer( CurrentVBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &VBuffers[CurrentVBuffer], NULL ) ) ) if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) )
{ {
Fail = true; Fail = true;
break; break;
} }
if( FAILED( D3D::dev->CreateIndexBuffer( CurrentIBufferSize * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &IBuffers[CurrentVBuffer], NULL ) ) ) if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) )
{ {
Fail = true; Fail = true;
return; return;
} }
} }
NumVBuffers = CurrentVBuffer; m_buffers_count = m_current_vertex_buffer;
CurrentVBuffer = 0; m_current_vertex_buffer = 0;
CurrentIBuffer = 0; m_current_index_buffer = 0;
CurrentIBufferIndex = CurrentIBufferSize; m_index_buffer_cursor = m_index_buffer_size;
CurrentVBufferIndex = CurrentVBufferSize; m_vertex_buffer_cursor = m_vertex_buffer_size;
m_current_stride = 0;
if (Fail) if (Fail)
{ {
NumVBuffers--; m_buffers_count--;
if (NumVBuffers < 2) if (m_buffers_count < 2)
{ {
//Error creating Vertex buffers. clean and fall to Vertex arrays //Error creating Vertex buffers. clean and fall to Vertex arrays
NumVBuffers = MAXVBUFFER_COUNT; m_buffers_count = MAX_VBUFFER_COUNT;
DestroyDeviceObjects(); DestroyDeviceObjects();
} }
} }
} }
void VertexManager::DestroyDeviceObjects() void VertexManager::DestroyDeviceObjects()
{ {
D3D::dev->SetStreamSource( 0, NULL, 0, 0); D3D::SetStreamSource( 0, NULL, 0, 0);
D3D::dev->SetIndices(NULL); D3D::SetIndices(NULL);
for (int i = 0; i < MAXVBUFFER_COUNT; i++) for (int i = 0; i < MAX_VBUFFER_COUNT; i++)
{ {
if(VBuffers) if(m_vertex_buffers)
{ {
if (VBuffers[i]) if (m_vertex_buffers[i])
{ {
VBuffers[i]->Release(); m_vertex_buffers[i]->Release();
VBuffers[i] = NULL; m_vertex_buffers[i] = NULL;
} }
} }
if (IBuffers[i]) if (m_index_buffers[i])
{ {
IBuffers[i]->Release(); m_index_buffers[i]->Release();
IBuffers[i] = NULL; m_index_buffers[i] = NULL;
} }
} }
if(VBuffers) if(m_vertex_buffers)
delete [] VBuffers; delete [] m_vertex_buffers;
if(IBuffers) if(m_index_buffers)
delete [] IBuffers; delete [] m_index_buffers;
VBuffers = NULL; m_vertex_buffers = NULL;
IBuffers = NULL; m_index_buffers = NULL;
} }
void VertexManager::PrepareVBuffers(int stride) void VertexManager::PrepareDrawBuffers(u32 stride)
{ {
if (!NumVBuffers) if (!m_buffers_count)
{ {
return; return;
} }
@ -158,34 +158,33 @@ void VertexManager::PrepareVBuffers(int stride)
int TdataSize = IndexGenerator::GetTriangleindexLen(); int TdataSize = IndexGenerator::GetTriangleindexLen();
int LDataSize = IndexGenerator::GetLineindexLen(); int LDataSize = IndexGenerator::GetLineindexLen();
int PDataSize = IndexGenerator::GetPointindexLen(); int PDataSize = IndexGenerator::GetPointindexLen();
int IndexDataSize = TdataSize + LDataSize + PDataSize; int IndexDataSize = TdataSize + LDataSize;
DWORD LockMode = D3DLOCK_NOOVERWRITE; DWORD LockMode = D3DLOCK_NOOVERWRITE;
m_vertex_buffer_cursor--;
if (CurrentVBufferIndex > CurrentVBufferSize - datasize) m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize)
{ {
LockMode = D3DLOCK_DISCARD; LockMode = D3DLOCK_DISCARD;
CurrentVBufferIndex = 0; m_vertex_buffer_cursor = 0;
CurrentVBuffer = (CurrentVBuffer + 1) % NumVBuffers; m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count;
} }
if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode)))
if(FAILED(VBuffers[CurrentVBuffer]->Lock(CurrentVBufferIndex, datasize,(VOID**)(&pVertices), LockMode)))
{ {
DestroyDeviceObjects(); DestroyDeviceObjects();
return; return;
} }
memcpy(pVertices, LocalVBuffer, datasize); memcpy(pVertices, LocalVBuffer, datasize);
VBuffers[CurrentVBuffer]->Unlock(); m_vertex_buffers[m_current_vertex_buffer]->Unlock();
LockMode = D3DLOCK_NOOVERWRITE; LockMode = D3DLOCK_NOOVERWRITE;
if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize)
if (CurrentIBufferIndex > CurrentIBufferSize - IndexDataSize)
{ {
LockMode = D3DLOCK_DISCARD; LockMode = D3DLOCK_DISCARD;
CurrentIBufferIndex = 0; m_index_buffer_cursor = 0;
CurrentIBuffer = (CurrentIBuffer + 1) % NumVBuffers; m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count;
} }
if(FAILED(IBuffers[CurrentIBuffer]->Lock(CurrentIBufferIndex * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode )))
{ {
DestroyDeviceObjects(); DestroyDeviceObjects();
return; return;
@ -200,72 +199,88 @@ void VertexManager::PrepareVBuffers(int stride)
memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16)); memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16));
pIndices += LDataSize; pIndices += LDataSize;
} }
if(PDataSize) m_index_buffers[m_current_index_buffer]->Unlock();
{ if(m_current_stride != stride || m_vertex_buffer_cursor == 0)
memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16));
}
IBuffers[CurrentIBuffer]->Unlock();
D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride);
if(CurrentIBufferIndex == 0)
{ {
D3D::dev->SetIndices(IBuffers[CurrentIBuffer]); m_current_stride = stride;
D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, stride);
} }
} if (m_index_buffer_cursor == 0)
void VertexManager::DrawVB(int stride)
{
if (IndexGenerator::GetNumTriangles() > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitive( D3D::SetIndices(m_index_buffers[m_current_index_buffer]);
D3DPT_TRIANGLELIST,
0,
0,
IndexGenerator::GetNumVerts(),
CurrentIBufferIndex,
IndexGenerator::GetNumTriangles())))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (IndexGenerator::GetNumLines() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_LINELIST,
0,
0,
IndexGenerator::GetNumVerts(),
CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen(),
IndexGenerator::GetNumLines())))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (IndexGenerator::GetNumPoints() > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_POINTLIST,
0,
0,
IndexGenerator::GetNumVerts(),
CurrentIBufferIndex + IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen(),
IndexGenerator::GetNumPoints())))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
} }
void VertexManager::DrawVA(int stride) void VertexManager::DrawVertexBuffer(int stride)
{ {
if (IndexGenerator::GetNumTriangles() > 0) int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts();
int StartIndex = m_index_buffer_cursor;
int basevertex = m_vertex_buffer_cursor / stride;
if (triangles > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
basevertex,
0,
numverts,
StartIndex,
triangles)))
{
DumpBadShaders();
}
StartIndex += IndexGenerator::GetTriangleindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (lines > 0)
{
if (FAILED(D3D::dev->DrawIndexedPrimitive(
D3DPT_LINELIST,
basevertex,
0,
numverts,
StartIndex,
IndexGenerator::GetNumLines())))
{
DumpBadShaders();
}
StartIndex += IndexGenerator::GetLineindexLen();
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
}
if (points > 0)
{
//DrawIndexedPrimitive does not support point list so we have to draw the points one by one
for (int i = 0; i < points; i++)
{
if (FAILED(D3D::dev->DrawPrimitive(
D3DPT_POINTLIST,
basevertex + PIBuffer[i],
1)))
{
DumpBadShaders();
}
INCSTAT(stats.thisFrame.numDrawCalls);
}
}
}
void VertexManager::DrawVertexArray(int stride)
{
int triangles = IndexGenerator::GetNumTriangles();
int lines = IndexGenerator::GetNumLines();
int points = IndexGenerator::GetNumPoints();
int numverts = IndexGenerator::GetNumVerts();
if (triangles > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST, D3DPT_TRIANGLELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), 0, numverts, triangles,
TIBuffer, TIBuffer,
D3DFMT_INDEX16, D3DFMT_INDEX16,
LocalVBuffer, LocalVBuffer,
@ -275,11 +290,11 @@ void VertexManager::DrawVA(int stride)
} }
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (IndexGenerator::GetNumLines() > 0) if (lines > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST, D3DPT_LINELIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), 0, numverts, lines,
LIBuffer, LIBuffer,
D3DFMT_INDEX16, D3DFMT_INDEX16,
LocalVBuffer, LocalVBuffer,
@ -289,11 +304,11 @@ void VertexManager::DrawVA(int stride)
} }
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (IndexGenerator::GetNumPoints() > 0) if (points > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST, D3DPT_POINTLIST,
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), 0, numverts, points,
PIBuffer, PIBuffer,
D3DFMT_INDEX16, D3DFMT_INDEX16,
LocalVBuffer, LocalVBuffer,
@ -307,11 +322,7 @@ void VertexManager::DrawVA(int stride)
void VertexManager::vFlush() void VertexManager::vFlush()
{ {
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed = true;
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
u32 usedtextures = 0; u32 usedtextures = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevorders[i / 2].getEnable(i & 1)) if (bpmem.tevorders[i / 2].getEnable(i & 1))
@ -350,7 +361,7 @@ void VertexManager::vFlush()
// set global constants // set global constants
VertexShaderManager::SetConstants(); VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants(); PixelShaderManager::SetConstants();
int stride = g_nativeVertexFmt->GetVertexStride(); u32 stride = g_nativeVertexFmt->GetVertexStride();
if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components)) if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components))
{ {
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
@ -362,9 +373,16 @@ void VertexManager::vFlush()
goto shader_fail; goto shader_fail;
} }
PrepareVBuffers(stride); PrepareDrawBuffers(stride);
g_nativeVertexFmt->SetupVertexPointers(); g_nativeVertexFmt->SetupVertexPointers();
if(NumVBuffers){ DrawVB(stride);} else { DrawVA(stride);} if(m_buffers_count)
{
DrawVertexBuffer(stride);
}
else
{
DrawVertexArray(stride);
}
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
@ -377,16 +395,23 @@ void VertexManager::vFlush()
} }
// update alpha only // update alpha only
g_renderer->ApplyState(true); g_renderer->ApplyState(true);
if(NumVBuffers){ DrawVB(stride);} else { DrawVA(stride);} if(m_buffers_count)
{
DrawVertexBuffer(stride);
}
else
{
DrawVertexArray(stride);
}
g_renderer->RestoreState(); g_renderer->RestoreState();
} }
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);
shader_fail: shader_fail:
if(NumVBuffers) if(m_buffers_count)
{ {
CurrentIBufferIndex += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen();
CurrentVBufferIndex += IndexGenerator::GetNumVerts() * stride; m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride;
} }
ResetBuffer(); ResetBuffer();
} }

View File

@ -34,18 +34,19 @@ public:
void CreateDeviceObjects(); void CreateDeviceObjects();
void DestroyDeviceObjects(); void DestroyDeviceObjects();
private: private:
u32 CurrentVBufferIndex; u32 m_vertex_buffer_cursor;
u32 CurrentVBufferSize; u32 m_vertex_buffer_size;
u32 CurrentIBufferIndex; u32 m_index_buffer_cursor;
u32 CurrentIBufferSize; u32 m_index_buffer_size;
u32 NumVBuffers; u32 m_buffers_count;
u32 CurrentVBuffer; u32 m_current_vertex_buffer;
u32 CurrentIBuffer; u32 m_current_stride;
LPDIRECT3DVERTEXBUFFER9 *VBuffers; u32 m_current_index_buffer;
LPDIRECT3DINDEXBUFFER9 *IBuffers; LPDIRECT3DVERTEXBUFFER9 *m_vertex_buffers;
void PrepareVBuffers(int stride); LPDIRECT3DINDEXBUFFER9 *m_index_buffers;
void DrawVB(int stride); void PrepareDrawBuffers(u32 stride);
void DrawVA(int stride); void DrawVertexBuffer(int stride);
void DrawVertexArray(int stride);
// temp // temp
void vFlush(); void vFlush();
}; };

View File

@ -26,48 +26,9 @@
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
#include "VertexManager.h" #include "VertexManager.h"
#define COMPILED_CODE_SIZE 4096
// TODO: Use this again for performance, but without VAO we never know exactly the last configuration
static u32 s_prevcomponents; // previous state set
/*
#ifdef _WIN32
#ifdef _M_IX86
#define USE_JIT
#endif
#endif
*/
// Note the use of CallCdeclFunction3I etc.
// This is a horrible hack that is necessary because in 64-bit mode, Opengl32.dll is based way, way above the 32-bit
// address space that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we
// want to grab the function pointers from the import table instead.
// This problem does not apply to glew functions, only core opengl32 functions.
// Here's some global state. We only use this to keep track of what we've sent to the OpenGL state // Here's some global state. We only use this to keep track of what we've sent to the OpenGL state
// machine. // machine.
#ifdef USE_JIT
DECLARE_IMPORT(glNormalPointer);
DECLARE_IMPORT(glVertexPointer);
DECLARE_IMPORT(glColorPointer);
DECLARE_IMPORT(glTexCoordPointer);
#endif
class GLVertexFormat : public NativeVertexFormat
{
u8 *m_compiledCode;
PortableVertexDeclaration vtx_decl;
public:
GLVertexFormat();
~GLVertexFormat();
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
virtual void SetupVertexPointers();
};
namespace OGL namespace OGL
{ {
@ -76,23 +37,14 @@ NativeVertexFormat* VertexManager::CreateNativeVertexFormat()
return new GLVertexFormat(); return new GLVertexFormat();
} }
}
GLVertexFormat::GLVertexFormat() GLVertexFormat::GLVertexFormat()
{ {
#ifdef USE_JIT
m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false);
if (m_compiledCode)
memset(m_compiledCode, 0, COMPILED_CODE_SIZE);
#endif
} }
GLVertexFormat::~GLVertexFormat() GLVertexFormat::~GLVertexFormat()
{ {
#ifdef USE_JIT glDeleteVertexArrays(1, &VAO);
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
m_compiledCode = 0;
#endif
} }
inline GLuint VarToGL(VarType t) inline GLuint VarToGL(VarType t)
@ -105,105 +57,44 @@ inline GLuint VarToGL(VarType t)
void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{ {
s_prevcomponents = 0; this->vtx_decl = _vtx_decl;
vertex_stride = vtx_decl.stride;
vertex_stride = _vtx_decl.stride;
using namespace Gen;
// We will not allow vertex components causing uneven strides. // We will not allow vertex components causing uneven strides.
if (_vtx_decl.stride & 3) if (vertex_stride & 3)
PanicAlert("Uneven vertex stride: %i", _vtx_decl.stride); PanicAlert("Uneven vertex stride: %i", vertex_stride);
#ifdef USE_JIT
Gen::XEmitter emit(m_compiledCode);
// Alright, we have our vertex declaration. Compile some crazy code to set it quickly using GL.
emit.ABI_EmitPrologue(6);
emit.CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, _vtx_decl.stride, 0); VertexManager *vm = (OGL::VertexManager*)g_vertex_manager;
if (_vtx_decl.num_normals >= 1) glGenVertexArrays(1, &VAO);
{ glBindVertexArray(VAO);
emit.CallCdeclFunction3_I(glNormalPointer, VarToGL(_vtx_decl.normal_gl_type), _vtx_decl.stride, _vtx_decl.normal_offset[0]);
if (_vtx_decl.num_normals == 3) { // the element buffer is bound directly to the vao, so we must it set for every vao
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[1]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->m_index_buffers);
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[2]); glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers);
}
} glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, (u8*)NULL);
for (int i = 0; i < 2; i++)
{
if (_vtx_decl.color_offset[i] != -1)
{
if (i == 0)
emit.CallCdeclFunction4_I(glColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
else
emit.CallCdeclFunction4((void *)glSecondaryColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
}
}
for (int i = 0; i < 8; i++)
{
if (_vtx_decl.texcoord_offset[i] != -1)
{
int id = GL_TEXTURE0 + i;
#ifdef _M_X64
#ifdef _MSC_VER
emit.MOV(32, R(RCX), Imm32(id));
#else
emit.MOV(32, R(RDI), Imm32(id));
#endif
#else
emit.ABI_AlignStack(1 * 4);
emit.PUSH(32, Imm32(id));
#endif
emit.CALL((void *)glClientActiveTexture);
#ifndef _M_X64
#ifdef _WIN32
// don't inc stack on windows, stdcall
#else
emit.ABI_RestoreStack(1 * 4);
#endif
#endif
emit.CallCdeclFunction4_I(
glTexCoordPointer, _vtx_decl.texcoord_size[i], VarToGL(_vtx_decl.texcoord_gl_type[i]),
_vtx_decl.stride, _vtx_decl.texcoord_offset[i]);
}
}
if (_vtx_decl.posmtx_offset != -1)
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, _vtx_decl.stride, _vtx_decl.posmtx_offset);
emit.ABI_EmitEpilogue(6);
if (emit.GetCodePtr() - (u8*)m_compiledCode > COMPILED_CODE_SIZE)
Crash();
#endif
this->vtx_decl = _vtx_decl;
}
void GLVertexFormat::SetupVertexPointers() {
// Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to
// get around type checking errors, and call it.
#ifdef USE_JIT
((void (*)())(void*)m_compiledCode)();
#else
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer);
if (vtx_decl.num_normals >= 1) { if (vtx_decl.num_normals >= 1) {
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0])); glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[0]);
if (vtx_decl.num_normals == 3) { if (vtx_decl.num_normals == 3) {
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[1])); glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[2])); glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[1]);
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (u8*)NULL + vtx_decl.normal_offset[2]);
} }
} }
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (vtx_decl.color_offset[i] != -1) { if (vtx_decl.color_offset[i] != -1) {
if (i == 0) if (i == 0) {
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i])); glEnableClientState(GL_COLOR_ARRAY);
else { glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]);
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i])); } else {
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (u8*)NULL + vtx_decl.color_offset[i]);
} }
} }
} }
@ -212,75 +103,21 @@ void GLVertexFormat::SetupVertexPointers() {
if (vtx_decl.texcoord_offset[i] != -1) { if (vtx_decl.texcoord_offset[i] != -1) {
int id = GL_TEXTURE0 + i; int id = GL_TEXTURE0 + i;
glClientActiveTexture(id); glClientActiveTexture(id);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]), glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]),
vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.texcoord_offset[i])); vtx_decl.stride, (u8*)NULL + vtx_decl.texcoord_offset[i]);
} }
} }
if (vtx_decl.posmtx_offset != -1) { if (vtx_decl.posmtx_offset != -1) {
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset)); glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (u8*)NULL + vtx_decl.posmtx_offset);
} }
#endif
if (s_prevcomponents != m_components) vm->m_last_vao = VAO;
{ }
// vertices
glEnableClientState(GL_VERTEX_ARRAY); void GLVertexFormat::SetupVertexPointers() {
}
// matrices
if ((m_components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX))
{
if (m_components & VB_HAS_POSMTXIDX)
glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
else
glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB);
}
// normals
if ((m_components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0))
{
if (m_components & VB_HAS_NRM0)
glEnableClientState(GL_NORMAL_ARRAY);
else
glDisableClientState(GL_NORMAL_ARRAY);
}
if ((m_components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1))
{
if (m_components & VB_HAS_NRM1) {
glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
}
else {
glDisableVertexAttribArray(SHADER_NORM1_ATTRIB);
glDisableVertexAttribArray(SHADER_NORM2_ATTRIB);
}
}
// color
for (int i = 0; i < 2; ++i)
{
if ((m_components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
{
if (m_components & (VB_HAS_COL0 << i))
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
else
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
}
}
// tex
for (int i = 0; i < 8; ++i)
{
if ((m_components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i)))
{
glClientActiveTexture(GL_TEXTURE0 + i);
if (m_components & (VB_HAS_UV0 << i))
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
else
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
s_prevcomponents = m_components;
}
} }

View File

@ -193,10 +193,6 @@ RasterFont::RasterFont()
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL); glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL);
glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB); glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB);
glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2); glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
RasterFont::~RasterFont() RasterFont::~RasterFont()
@ -288,10 +284,6 @@ void RasterFont::printMultilineText(const char *text, double start_x, double sta
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
glDrawArrays(GL_TRIANGLES, 0, usage/4); glDrawArrays(GL_TRIANGLES, 0, usage/4);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0); glUseProgram(0);
} }

View File

@ -64,6 +64,7 @@
#include "BPFunctions.h" #include "BPFunctions.h"
#include "FPSCounter.h" #include "FPSCounter.h"
#include "ConfigManager.h" #include "ConfigManager.h"
#include "VertexManager.h"
#include "main.h" // Local #include "main.h" // Local
#ifdef _WIN32 #ifdef _WIN32
@ -296,6 +297,20 @@ Renderer::Renderer()
"GPU: Does your video card support OpenGL 3.0?"); "GPU: Does your video card support OpenGL 3.0?");
bSuccess = false; bSuccess = false;
} }
if (!GLEW_ARB_map_buffer_range)
{
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_map_buffer_range.\n"
"GPU: Does your video card support OpenGL 3.0?");
bSuccess = false;
}
if (!GLEW_ARB_draw_elements_base_vertex)
{
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_draw_elements_base_vertex.\n"
"GPU: Does your video card support OpenGL 3.2?");
bSuccess = false;
}
s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL;
@ -415,10 +430,6 @@ Renderer::Renderer()
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*5, NULL); glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*5, NULL);
glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB); glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB);
glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 3, GL_FLOAT, 0, sizeof(GLfloat)*5, (GLfloat*)NULL+2); glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 3, GL_FLOAT, 0, sizeof(GLfloat)*5, (GLfloat*)NULL+2);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glStencilFunc(GL_ALWAYS, 0, 0); glStencilFunc(GL_ALWAYS, 0, 0);
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
@ -603,10 +614,6 @@ void Renderer::DrawDebugInfo()
ProgramShaderCache::SetBothShaders(s_ShowEFBCopyRegions_PS.glprogid, s_ShowEFBCopyRegions_VS.glprogid); ProgramShaderCache::SetBothShaders(s_ShowEFBCopyRegions_PS.glprogid, s_ShowEFBCopyRegions_VS.glprogid);
glBindVertexArray( s_ShowEFBCopyRegions_VAO ); glBindVertexArray( s_ShowEFBCopyRegions_VAO );
glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6); glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Restore Line Size // Restore Line Size
glLineWidth(lSize); glLineWidth(lSize);
@ -1429,6 +1436,10 @@ void Renderer::RestoreAPIState()
glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL);
ProgramShaderCache::SetBothShaders(0, 0); ProgramShaderCache::SetBothShaders(0, 0);
VertexManager *vm = (OGL::VertexManager*)g_vertex_manager;
glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers);
vm->m_last_vao = 0;
} }
void Renderer::SetGenerationMode() void Renderer::SetGenerationMode()

View File

@ -375,10 +375,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
glBindVertexArray(vbo_it->second.vao); glBindVertexArray(vbo_it->second.vao);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);

View File

@ -183,10 +183,6 @@ void Init()
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL); glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL);
glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB); glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB);
glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2); glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenRenderbuffers(1, &s_dstRenderBuffer); glGenRenderbuffers(1, &s_dstRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer);
@ -285,10 +281,6 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
glBindVertexArray( s_encode_VAO ); glBindVertexArray( s_encode_VAO );
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -475,10 +467,6 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
glBindVertexArray( s_decode_VAO ); glBindVertexArray( s_decode_VAO );
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
// reset state // reset state

View File

@ -49,58 +49,177 @@ extern NativeVertexFormat *g_nativeVertexFmt;
namespace OGL namespace OGL
{ {
//This are the initially requeted size for the buffers expresed in bytes
//static GLint max_Index_size = 0; const u32 MAX_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 16 * sizeof(u16);
const u32 MAX_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 16;
//static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0}; const u32 MIN_IBUFFER_SIZE = VertexManager::MAXIBUFFERSIZE * 1 * sizeof(u16);
//static int s_nCurVBOIndex = 0; // current free buffer const u32 MIN_VBUFFER_SIZE = VertexManager::MAXVBUFFERSIZE * 1;
VertexManager::VertexManager() VertexManager::VertexManager()
{ {
// TODO: doesn't seem to be used anywhere CreateDeviceObjects();
}
//glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size); VertexManager::~VertexManager()
// {
//if (max_Index_size > MAXIBUFFERSIZE) DestroyDeviceObjects();
// max_Index_size = MAXIBUFFERSIZE;
//
//GL_REPORT_ERRORD();
} }
void VertexManager::CreateDeviceObjects() void VertexManager::CreateDeviceObjects()
{ {
GL_REPORT_ERRORD();
u32 max_Index_size = 0;
u32 max_Vertex_size = 0;
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*)&max_Index_size);
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*)&max_Vertex_size);
max_Index_size *= sizeof(u16);
GL_REPORT_ERROR();
m_index_buffer_size = std::min(MAX_IBUFFER_SIZE, std::max(max_Index_size, MIN_IBUFFER_SIZE));
m_vertex_buffer_size = std::min(MAX_VBUFFER_SIZE, std::max(max_Vertex_size, MIN_VBUFFER_SIZE));
// should be not bigger, but we need it. so try and have luck
if (m_index_buffer_size > max_Index_size) {
ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_INDICES to small, so try it anyway. good luck\n");
}
if (m_vertex_buffer_size > max_Vertex_size) {
ERROR_LOG(VIDEO, "GL_MAX_ELEMENTS_VERTICES to small, so try it anyway. good luck\n");
}
glGenBuffers(1, &m_vertex_buffers);
GL_REPORT_ERROR();
glGenBuffers(1, &m_index_buffers);
GL_REPORT_ERROR();
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffers );
GL_REPORT_ERROR();
glBufferData(GL_ARRAY_BUFFER, m_vertex_buffer_size, NULL, GL_STREAM_DRAW );
GL_REPORT_ERROR();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffers );
GL_REPORT_ERROR();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_size, NULL, GL_STREAM_DRAW );
GL_REPORT_ERROR();
m_index_buffer_cursor = 0;
m_vertex_buffer_cursor = 0;
m_CurrentVertexFmt = NULL;
m_last_vao = 0;
} }
void VertexManager::DestroyDeviceObjects() void VertexManager::DestroyDeviceObjects()
{ {
GL_REPORT_ERRORD();
glBindBuffer(GL_ARRAY_BUFFER, 0 );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 );
GL_REPORT_ERROR();
glDeleteBuffers(1, &m_vertex_buffers);
GL_REPORT_ERROR();
glDeleteBuffers(1, &m_index_buffers);
GL_REPORT_ERROR();
} }
void VertexManager::Draw() void VertexManager::PrepareDrawBuffers(u32 stride)
{ {
if (IndexGenerator::GetNumTriangles() > 0) u8* pVertices = NULL;
u16* pIndices = NULL;
int vertex_data_size = IndexGenerator::GetNumVerts() * stride;
int triangle_index_size = IndexGenerator::GetTriangleindexLen();
int line_index_size = IndexGenerator::GetLineindexLen();
int point_index_size = IndexGenerator::GetPointindexLen();
int index_data_size = (triangle_index_size + line_index_size + point_index_size) * sizeof(u16);
GLbitfield LockMode = GL_MAP_WRITE_BIT;
m_vertex_buffer_cursor--;
m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride;
if (m_vertex_buffer_cursor >= m_vertex_buffer_size - vertex_data_size || m_index_buffer_cursor >= m_index_buffer_size - index_data_size)
{ {
glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer); LockMode |= GL_MAP_INVALIDATE_BUFFER_BIT;
m_vertex_buffer_cursor = 0;
m_index_buffer_cursor = 0;
}
else
{
LockMode |= /*GL_MAP_INVALIDATE_RANGE_BIT |*/ GL_MAP_UNSYNCHRONIZED_BIT;
}
pVertices = (u8*)glMapBufferRange(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LockMode);
if(pVertices)
{
memcpy(pVertices, LocalVBuffer, vertex_data_size);
glUnmapBuffer(GL_ARRAY_BUFFER);
}
else // could that happen? out-of-memory?
{
glBufferSubData(GL_ARRAY_BUFFER, m_vertex_buffer_cursor, vertex_data_size, LocalVBuffer);
}
pIndices = (u16*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor , index_data_size, LockMode);
if(pIndices)
{
if(triangle_index_size)
{
memcpy(pIndices, TIBuffer, triangle_index_size * sizeof(u16));
pIndices += triangle_index_size;
}
if(line_index_size)
{
memcpy(pIndices, LIBuffer, line_index_size * sizeof(u16));
pIndices += line_index_size;
}
if(point_index_size)
{
memcpy(pIndices, PIBuffer, point_index_size * sizeof(u16));
}
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
}
else // could that happen? out-of-memory?
{
if(triangle_index_size)
{
triangle_index_size *= sizeof(u16);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor, triangle_index_size, TIBuffer);
}
if(line_index_size)
{
line_index_size *= sizeof(u16);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size, line_index_size, LIBuffer);
}
if(point_index_size)
{
point_index_size *= sizeof(u16);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer_cursor + triangle_index_size + line_index_size, point_index_size, PIBuffer);
}
}
}
void VertexManager::Draw(u32 stride)
{
int triangle_index_size = IndexGenerator::GetTriangleindexLen();
int line_index_size = IndexGenerator::GetLineindexLen();
int point_index_size = IndexGenerator::GetPointindexLen();
int StartIndex = m_index_buffer_cursor;
int basevertex = m_vertex_buffer_cursor / stride;
if (triangle_index_size > 0)
{
glDrawElementsBaseVertex(GL_TRIANGLES, triangle_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex);
StartIndex += triangle_index_size * sizeof(u16);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (IndexGenerator::GetNumLines() > 0) if (line_index_size > 0)
{ {
glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer); glDrawElementsBaseVertex(GL_LINES, line_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex);
StartIndex += line_index_size * sizeof(u16);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if (IndexGenerator::GetNumPoints() > 0) if (point_index_size > 0)
{ {
glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer); glDrawElementsBaseVertex(GL_POINTS, point_index_size, GL_UNSIGNED_SHORT, (u8*)NULL+StartIndex, basevertex);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
} }
void VertexManager::vFlush() void VertexManager::vFlush()
{ {
if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return;
Flushed=true;
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGen.numTexGens, PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGen.numTexGens,
@ -132,10 +251,15 @@ void VertexManager::vFlush()
(void)GL_REPORT_ERROR(); (void)GL_REPORT_ERROR();
//glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]); GLVertexFormat *nativeVertexFmt = (GLVertexFormat*)g_nativeVertexFmt;
//glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW); u32 stride = nativeVertexFmt->GetVertexStride();
GL_REPORT_ERRORD();
if(m_last_vao != nativeVertexFmt->VAO) {
glBindVertexArray(nativeVertexFmt->VAO);
m_last_vao = nativeVertexFmt->VAO;
}
PrepareDrawBuffers(stride);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
u32 usedtextures = 0; u32 usedtextures = 0;
@ -148,7 +272,7 @@ void VertexManager::vFlush()
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
for (int i = 0; i < 8; i++) for (u32 i = 0; i < 8; i++)
{ {
if (usedtextures & (1 << i)) if (usedtextures & (1 << i))
{ {
@ -215,7 +339,7 @@ void VertexManager::vFlush()
g_nativeVertexFmt->SetupVertexPointers(); g_nativeVertexFmt->SetupVertexPointers();
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
Draw(); Draw(stride);
// run through vertex groups again to set alpha // run through vertex groups again to set alpha
if (useDstAlpha && !dualSourcePossible) if (useDstAlpha && !dualSourcePossible)
@ -235,7 +359,8 @@ void VertexManager::vFlush()
glDisable(GL_BLEND); glDisable(GL_BLEND);
Draw(); Draw(stride);
// restore color mask // restore color mask
g_renderer->SetColorMask(); g_renderer->SetColorMask();
@ -243,11 +368,11 @@ void VertexManager::vFlush()
glEnable(GL_BLEND); glEnable(GL_BLEND);
} }
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers); m_index_buffer_cursor += (IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen()) * sizeof(u16);
s_pCurBufferPointer = LocalVBuffer; m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride;
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
ResetBuffer();
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS) if (g_ActiveConfig.iLog & CONF_SAVESHADERS)
{ {

View File

@ -24,6 +24,19 @@
namespace OGL namespace OGL
{ {
class GLVertexFormat : public NativeVertexFormat
{
PortableVertexDeclaration vtx_decl;
public:
GLVertexFormat();
~GLVertexFormat();
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
virtual void SetupVertexPointers();
GLuint VAO;
};
// Handles the OpenGL details of drawing lots of vertices quickly. // Handles the OpenGL details of drawing lots of vertices quickly.
// Other functionality is moving out. // Other functionality is moving out.
@ -31,14 +44,24 @@ class VertexManager : public ::VertexManager
{ {
public: public:
VertexManager(); VertexManager();
~VertexManager();
NativeVertexFormat* CreateNativeVertexFormat(); NativeVertexFormat* CreateNativeVertexFormat();
void CreateDeviceObjects(); void CreateDeviceObjects();
void DestroyDeviceObjects(); void DestroyDeviceObjects();
// NativeVertexFormat use this
GLuint m_vertex_buffers;
GLuint m_index_buffers;
GLuint m_last_vao;
private: private:
void Draw(); void Draw(u32 stride);
// temp
void vFlush(); void vFlush();
void PrepareDrawBuffers(u32 stride);
u32 m_vertex_buffer_cursor;
u32 m_vertex_buffer_size;
u32 m_index_buffer_cursor;
u32 m_index_buffer_size;
NativeVertexFormat *m_CurrentVertexFmt;
}; };
} }