diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index bfc85cf41a..7ad10d0235 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -20,7 +20,7 @@ std::vector FormatVertexData(const rsx::data_array_format_in const rsx::data_array_format_info &vertexData = vertex_array_desc[i]; if (!vertexData.size) continue; - u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 * i]; + u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + i]; u32 addr = rsx::get_address(addrRegVal & 0x7fffffff, addrRegVal >> 31); size_t elementCount = ((vertexData.array) ? vertex_data_size[i] : vertex_data[i].size()) / (vertexData.size * rsx::get_vertex_type_size(vertexData.type)); @@ -61,7 +61,7 @@ void uploadVertexData(const VertexBufferFormat &vbf, const rsx::data_array_forma { for (size_t attributeId : vbf.attributeId) { - u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 * attributeId]; + u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + attributeId]; u32 addr = rsx::get_address(addrRegVal & 0x7fffffff, addrRegVal >> 31); if (!vertex_array_desc[attributeId].array) diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index 49ae5616e4..1c9f18e059 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -136,13 +136,13 @@ void VertexProgramDecompiler::SetDST(bool is_sca, std::string value) std::string mask = GetMask(is_sca); - value += mask; - - if (is_sca && d0.vec_result) + if (is_sca) { - //value = "vec4(" + value + ")"; + value = getFloatTypeName(4) + "(" + value + ")"; } + value += mask; + if (d0.staturate) { value = "clamp(" + value + ", 0.0, 1.0)"; @@ -309,7 +309,7 @@ void VertexProgramDecompiler::AddCodeCond(const std::string& dst, const std::str if (dst_var.swizzles[0].length() == 1) { - AddCode("if (" + cond + ".x) " + dst + " = " + getFloatTypeName(4) + "(" + src + ".xxxx).x;"); + AddCode("if (" + cond + ".x) " + dst + " = " + src + ";"); } else { @@ -559,7 +559,7 @@ std::string VertexProgramDecompiler::Decompile() case RSX_SCA_OPCODE_MOV: SetDSTSca("$s"); break; case RSX_SCA_OPCODE_RCP: SetDSTSca("(1.0 / $s)"); break; case RSX_SCA_OPCODE_RCC: SetDSTSca("clamp(1.0 / $s, 5.42101e-20, 1.884467e19)"); break; - case RSX_SCA_OPCODE_RSQ: SetDSTSca("1.f / sqrt($s)"); break; + case RSX_SCA_OPCODE_RSQ: SetDSTSca("(1.f / sqrt($s))"); break; case RSX_SCA_OPCODE_EXP: SetDSTSca("exp($s)"); break; case RSX_SCA_OPCODE_LOG: SetDSTSca("log($s)"); break; case RSX_SCA_OPCODE_LIT: SetDSTSca(getFloatTypeName(4) + "(1.0, $s.x, ($s.x > 0.0 ? exp($s.w * log2($s.y)) : 0.0), 1.0)"); break; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index ebda80f0ff..617a2da8cd 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -92,27 +92,27 @@ DXGI_FORMAT getFormat(u8 type, u8 size) } static -std::vector getIALayout(ID3D12Device *device, const std::vector &vertexBufferFormat, const rsx::data_array_format_info *m_vertex_data, size_t baseOffset) +std::vector getIALayout(const rsx::data_array_format_info *vertex_info, const std::vector *vertex_data) { std::vector result; - for (size_t inputSlot = 0; inputSlot < vertexBufferFormat.size(); inputSlot++) + size_t inputSlot = 0; + for (size_t index = 0; index < rsx::limits::vertex_count; index++) { - for (size_t attributeId : vertexBufferFormat[inputSlot].attributeId) - { - u32 addrRegVal = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 * attributeId]; - u32 addr = rsx::get_address(addrRegVal & 0x7fffffff, addrRegVal >> 31); - const rsx::data_array_format_info &vertexData = m_vertex_data[attributeId]; + const auto &info = vertex_info[index]; + + if (!info.size) + continue; + D3D12_INPUT_ELEMENT_DESC IAElement = {}; IAElement.SemanticName = "TEXCOORD"; - IAElement.SemanticIndex = (UINT)attributeId; - IAElement.InputSlot = (UINT)inputSlot; - IAElement.Format = getFormat(vertexData.type - 1, vertexData.size); - IAElement.AlignedByteOffset = (UINT)(addr + baseOffset - vertexBufferFormat[inputSlot].range.first); - IAElement.InputSlotClass = (addr > 0) ? D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA : D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; - IAElement.InstanceDataStepRate = (addr > 0) ? 0 : 1; + IAElement.SemanticIndex = (UINT)index; + IAElement.InputSlot = (UINT)inputSlot++; + IAElement.Format = getFormat(info.type - 1, info.size); + IAElement.AlignedByteOffset = 0; + IAElement.InputSlotClass = info.array ? D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA : D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA; + IAElement.InstanceDataStepRate = 0; result.push_back(IAElement); - } } return result; } @@ -121,22 +121,19 @@ std::vector getIALayout(ID3D12Device *device, const st /** - * Suballocate a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap. + * */ static -D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const VertexBufferFormat &vbf, const rsx::data_array_format_info *vertex_array_desc, const std::vector *vertex_data, size_t baseOffset, ID3D12Device *device, DataHeap &vertexIndexHeap) +D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector &vertex_data, ID3D12Device *device, DataHeap &vertexIndexHeap) { - size_t subBufferSize = vbf.range.second - vbf.range.first + 1; - // Make multiple of stride - if (vbf.stride) - subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride; + size_t subBufferSize = vertex_data.size(); assert(vertexIndexHeap.canAlloc(subBufferSize)); size_t heapOffset = vertexIndexHeap.alloc(subBufferSize); void *buffer; ThrowIfFailed(vertexIndexHeap.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); void *bufferMap = (char*)buffer + heapOffset; - uploadVertexData(vbf, vertex_array_desc, vertex_data, baseOffset, bufferMap); + memcpy(bufferMap, vertex_data.data(), vertex_data.size()); vertexIndexHeap.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); return vertexIndexHeap.m_heap->GetGPUVirtualAddress() + heapOffset; } @@ -145,26 +142,21 @@ std::vector D3D12GSRender::UploadVertexBuffers(bool in { u32 m_vertex_data_base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; std::vector result; - const std::vector &vertexBufferFormat = FormatVertexData(vertex_arrays_info, vertex_arrays, m_vertexBufferSize, m_vertex_data_base_offset); - m_IASet = getIALayout(m_device.Get(), vertexBufferFormat, vertex_arrays_info, m_vertex_data_base_offset); + m_IASet = getIALayout(vertex_arrays_info, vertex_arrays); - const u32 data_offset = indexed_draw ? 0 : draw_array_first; - - for (size_t buffer = 0; buffer < vertexBufferFormat.size(); buffer++) + for (int index = 0; index < rsx::limits::vertex_count; ++index) { - const VertexBufferFormat &vbf = vertexBufferFormat[buffer]; - // Make multiple of stride - size_t subBufferSize = vbf.range.second - vbf.range.first + 1; - if (vbf.stride) - subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride; + const auto &info = vertex_arrays_info[index]; - D3D12_GPU_VIRTUAL_ADDRESS virtualAddress = createVertexBuffer(vbf, vertex_arrays_info, vertex_arrays, m_vertex_data_base_offset, m_device.Get(), m_vertexIndexData); - m_timers.m_bufferUploadSize += subBufferSize; + if (!info.size) + continue; + + D3D12_GPU_VIRTUAL_ADDRESS virtualAddress = createVertexBuffer(info, vertex_arrays[index], m_device.Get(), m_vertexIndexData); D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; vertexBufferView.BufferLocation = virtualAddress; - vertexBufferView.SizeInBytes = (UINT)subBufferSize; - vertexBufferView.StrideInBytes = (UINT)vbf.stride; + vertexBufferView.SizeInBytes = (UINT)vertex_arrays[index].size(); + vertexBufferView.StrideInBytes = (UINT)rsx::get_vertex_type_size(info.type) * info.size; result.push_back(vertexBufferView); } @@ -179,13 +171,15 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) if (!indexed_draw && isNativePrimitiveMode(draw_mode)) { m_renderingInfo.m_indexed = false; - m_renderingInfo.m_count = draw_array_count; - m_renderingInfo.m_baseVertex = draw_array_first; + m_renderingInfo.m_count = vertex_draw_count; + m_renderingInfo.m_baseVertex = 0; return indexBufferView; } m_renderingInfo.m_indexed = true; + u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; + // Index type size_t indexSize; if (!indexed_draw) @@ -195,7 +189,7 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) } else { - switch (m_indexed_array.m_type) + switch (indexed_type) { default: abort(); case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: @@ -210,11 +204,11 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) } // Index count - m_renderingInfo.m_count = getIndexCount(draw_mode, indexed_draw ? (u32)(m_indexed_array.m_data.size() / indexSize) : draw_array_count); + m_renderingInfo.m_count = getIndexCount(draw_mode, indexed_draw ? (u32)(vertex_index_array.size() / indexSize) : vertex_draw_count); // Base vertex if (!indexed_draw && isNativePrimitiveMode(draw_mode)) - m_renderingInfo.m_baseVertex = draw_array_first; + m_renderingInfo.m_baseVertex = 0; else m_renderingInfo.m_baseVertex = 0; @@ -227,7 +221,7 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw) void *buffer; ThrowIfFailed(m_vertexIndexData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize), (void**)&buffer)); void *bufferMap = (char*)buffer + heapOffset; - uploadIndexData(draw_mode, m_indexed_array.m_type, indexed_draw ? m_indexed_array.m_data.data() : nullptr, bufferMap, indexed_draw ? (u32)(m_indexed_array.m_data.size() / indexSize) : draw_array_count); + uploadIndexData(draw_mode, indexed_type, indexed_draw ? vertex_index_array.data() : nullptr, bufferMap, indexed_draw ? (u32)(vertex_index_array.size() / indexSize) : vertex_draw_count); m_vertexIndexData.m_heap->Unmap(0, &CD3DX12_RANGE(heapOffset, heapOffset + subBufferSize)); m_timers.m_bufferUploadSize += subBufferSize; indexBufferView.SizeInBytes = (UINT)subBufferSize; @@ -249,14 +243,14 @@ void D3D12GSRender::setScaleOffset() int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; // Scale - scaleOffsetMat[0] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (clip_w / 2.f); - scaleOffsetMat[5] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (clip_h / 2.f); - scaleOffsetMat[10] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)]; + scaleOffsetMat[0] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE] / (clip_w / 2.f); + scaleOffsetMat[5] *= (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 1] / (clip_h / 2.f); + scaleOffsetMat[10] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 2]; // Offset - scaleOffsetMat[3] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 0)] - (clip_w / 2.f); - scaleOffsetMat[7] = -((float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 1)] - (clip_h / 2.f)); - scaleOffsetMat[11] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)]; + scaleOffsetMat[3] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET] - (clip_w / 2.f); + scaleOffsetMat[7] = -((float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 1] - (clip_h / 2.f)); + scaleOffsetMat[11] = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 2]; scaleOffsetMat[3] /= clip_w / 2.f; scaleOffsetMat[7] /= clip_h / 2.f; @@ -285,6 +279,9 @@ void D3D12GSRender::setScaleOffset() void D3D12GSRender::FillVertexShaderConstantsBuffer() { + for (const auto &entry : transform_constants) + local_transform_constants[entry.first] = entry.second; + size_t bufferSize = 512 * 4 * sizeof(float); assert(m_constantsData.canAlloc(bufferSize)); @@ -292,7 +289,7 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer() void *constantsBufferMap; ThrowIfFailed(m_constantsData.m_heap->Map(0, &CD3DX12_RANGE(heapOffset, heapOffset + bufferSize), &constantsBufferMap)); - for (const auto &entry : transform_constants) + for (const auto &entry : local_transform_constants) { float data[4] = { entry.second.x, @@ -332,7 +329,7 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer() // Is it assigned by color register in command buffer ? // TODO : we loop every iteration, we might do better... bool isCommandBufferSetConstant = false; - for (const auto& entry : fragment_constants) +/* for (const auto& entry : fragment_constants) { size_t fragmentId = entry.first - fragment_program.offset; if (fragmentId == offsetInFP) @@ -344,7 +341,7 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer() vector[3] = (u32&)entry.second.w; break; } - } + }*/ if (!isCommandBufferSetConstant) { auto data = vm::ps3::ptr::make(fragment_program.addr + (u32)offsetInFP); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 4912990e0f..e45c6c0392 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -291,10 +291,6 @@ void D3D12GSRender::onexit_thread() { } -void D3D12GSRender::OnReset() -{ -} - bool D3D12GSRender::domethod(u32 cmd, u32 arg) { switch (cmd) @@ -411,35 +407,10 @@ void D3D12GSRender::end() std::chrono::time_point vertexIndexDurationStart = std::chrono::system_clock::now(); - // Init vertex count - if (m_indexed_array.m_count) + if (!vertex_index_array.empty() || vertex_draw_count) { - for (u32 i = 0; i < rsx::limits::vertex_count; ++i) - { - if (!vertex_arrays_info[i].size) continue; - if (!vertex_arrays_info[i].array) continue; - - const u32 tsize = rsx::get_vertex_type_size(vertex_arrays_info[i].type); - m_vertexBufferSize[i] = (m_indexed_array.index_min + m_indexed_array.index_max - m_indexed_array.index_min + 1) * tsize * vertex_arrays_info[i].size; - } - } - else - { - for (u32 i = 0; i < rsx::limits::vertex_count; ++i) - { - if (!vertex_arrays_info[i].size) continue; - if (!vertex_arrays_info[i].array) continue; - - const u32 tsize = rsx::get_vertex_type_size(vertex_arrays_info[i].type); - m_vertexBufferSize[i] = (draw_array_first + draw_array_count) * tsize * vertex_arrays_info[i].size; - } - } - - - if (m_indexed_array.m_count || draw_array_count) - { - const std::vector &vertexBufferViews = UploadVertexBuffers(m_indexed_array.m_count ? true : false); - const D3D12_INDEX_BUFFER_VIEW &indexBufferView = uploadIndexBuffers(m_indexed_array.m_count ? true : false); + const std::vector &vertexBufferViews = UploadVertexBuffers(!vertex_index_array.empty()); + const D3D12_INDEX_BUFFER_VIEW &indexBufferView = uploadIndexBuffers(!vertex_index_array.empty()); getCurrentResourceStorage().m_commandList->IASetVertexBuffers(0, (UINT)vertexBufferViews.size(), vertexBufferViews.data()); if (m_renderingInfo.m_indexed) getCurrentResourceStorage().m_commandList->IASetIndexBuffer(&indexBufferView); @@ -624,7 +595,7 @@ void D3D12GSRender::end() else getCurrentResourceStorage().m_commandList->DrawInstanced((UINT)m_renderingInfo.m_count, 1, (UINT)m_renderingInfo.m_baseVertex, 0); - m_indexed_array.Reset(); + vertex_index_array.clear(); std::chrono::time_point endDuration = std::chrono::system_clock::now(); m_timers.m_drawCallDuration += std::chrono::duration_cast(endDuration - startDuration).count(); m_timers.m_drawCallCount++; @@ -669,9 +640,9 @@ void D3D12GSRender::flip(int buffer) size_t w = 0, h = 0, rowPitch = 0; size_t offset = 0; - if (m_read_buffer) + if (false) { - CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); + CellGcmDisplayInfo* buffers;// = vm::get_ptr(m_gcm_buffers_addr); u32 addr = rsx::get_address(buffers[gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); w = buffers[gcm_current_buffer].width; h = buffers[gcm_current_buffer].height; @@ -818,6 +789,7 @@ void D3D12GSRender::flip(int buffer) storage.m_getPosUAVHeap = m_UAVHeap.getCurrentPutPosMinusOne(); // Flush + local_transform_constants.clear(); m_texturesRTTs.clear(); // Now get ready for next frame diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index c06ba71ee6..751ad50d4d 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -310,11 +310,12 @@ private: // Copy of RTT to be used as texture std::unordered_map m_texturesRTTs; + rsx::surface_info m_surface; + RSXFragmentProgram fragment_program; PipelineStateObjectCache m_cachePSO; std::pair *m_PSO; - - size_t m_vertexBufferSize[32]; + std::unordered_map local_transform_constants; struct { @@ -455,13 +456,9 @@ public: D3D12GSRender(); virtual ~D3D12GSRender(); - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override; - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override; - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override; - virtual void notifyProgramChange() override; - virtual void notifyBlendStateChange() override; - virtual void notifyDepthStencilStateChange() override; - virtual void notifyRasterizerStateChange() override; + virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value); + virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value); + virtual void semaphorePFIFOAcquire(u32 offset, u32 value); private: void InitD2DStructures(); @@ -512,7 +509,6 @@ private: protected: virtual void onexit_thread() override; - virtual void OnReset() override; virtual bool domethod(u32 cmd, u32 arg) override; virtual void end() override; virtual void flip(int buffer) override; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index c34ef6b36f..69a8d45c3a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -33,36 +33,29 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st) } } -void D3D12GSRender::notifyProgramChange() -{ - m_PSO = nullptr; -} -void D3D12GSRender::notifyBlendStateChange() -{ - m_PSO = nullptr; -} -void D3D12GSRender::notifyDepthStencilStateChange() -{ - m_PSO = nullptr; -} -void D3D12GSRender::notifyRasterizerStateChange() -{ - m_PSO = nullptr; -} - bool D3D12GSRender::LoadProgram() { + RSXVertexProgram vertex_program; + u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + vertex_program.data.reserve((512 - transform_program_start) * 4); + + for (int i = transform_program_start; i < 512; ++i) + { + vertex_program.data.resize((i - transform_program_start) * 4 + 4); + memcpy(vertex_program.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32)); + + D3 d3; + d3.HEX = transform_program[i * 4 + 3]; + + if (d3.end) + break; + } + u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; fragment_program.offset = shader_program & ~0x3; fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1); fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; - if (!m_cur_vertex_prog) - { - LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL"); - return false; - } - D3D12PipelineProperties prop = {}; switch (draw_mode - 1) { @@ -300,7 +293,7 @@ bool D3D12GSRender::LoadProgram() prop.IASet = m_IASet; - m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, &fragment_program, prop, std::make_pair(m_device.Get(), m_rootSignatures)); + m_PSO = m_cachePSO.getGraphicPipelineState(&vertex_program, &fragment_program, prop, std::make_pair(m_device.Get(), m_rootSignatures)); return m_PSO != nullptr; } diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index c36e69af5c..c726b8635f 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -1,4 +1,6 @@ #pragma once +#include "Utilities/types.h" +#include "Emu/Memory/vm.h" enum { @@ -132,87 +134,6 @@ enum CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE = 6, CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER = 7, CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP = 8, - - // Logic Op - CELL_GCM_CLEAR = 0x1500, - CELL_GCM_AND = 0x1501, - CELL_GCM_AND_REVERSE = 0x1502, - CELL_GCM_COPY = 0x1503, - CELL_GCM_AND_INVERTED = 0x1504, - CELL_GCM_NOOP = 0x1505, - CELL_GCM_XOR = 0x1506, - CELL_GCM_OR = 0x1507, - CELL_GCM_NOR = 0x1508, - CELL_GCM_EQUIV = 0x1509, - CELL_GCM_INVERT = 0x150A, - CELL_GCM_OR_REVERSE = 0x150B, - CELL_GCM_COPY_INVERTED = 0x150C, - CELL_GCM_OR_INVERTED = 0x150D, - CELL_GCM_NAND = 0x150E, - CELL_GCM_SET = 0x150F, - - // Blend Op - CELL_GCM_FUNC_ADD = 0x8006, - CELL_GCM_MIN = 0x8007, - CELL_GCM_MAX = 0x8008, - CELL_GCM_FUNC_SUBTRACT = 0x800A, - CELL_GCM_FUNC_REVERSE_SUBTRACT = 0x800B, - CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED = 0x0000F005, - CELL_GCM_FUNC_ADD_SIGNED = 0x0000F006, - CELL_GCM_FUNC_REVERSE_ADD_SIGNED = 0x0000F007, - - // Blend Factor - CELL_GCM_ZERO = 0, - CELL_GCM_ONE = 1, - CELL_GCM_SRC_COLOR = 0x0300, - CELL_GCM_ONE_MINUS_SRC_COLOR = 0x0301, - CELL_GCM_SRC_ALPHA = 0x0302, - CELL_GCM_ONE_MINUS_SRC_ALPHA = 0x0303, - CELL_GCM_DST_ALPHA = 0x0304, - CELL_GCM_ONE_MINUS_DST_ALPHA = 0x0305, - CELL_GCM_DST_COLOR = 0x0306, - CELL_GCM_ONE_MINUS_DST_COLOR = 0x0307, - CELL_GCM_SRC_ALPHA_SATURATE = 0x0308, - CELL_GCM_CONSTANT_COLOR = 0x8001, - CELL_GCM_ONE_MINUS_CONSTANT_COLOR = 0x8002, - CELL_GCM_CONSTANT_ALPHA = 0x8003, - CELL_GCM_ONE_MINUS_CONSTANT_ALPHA = 0x8004, - - // Stencil/Depth Compare Function - CELL_GCM_NEVER = 0x0200, - CELL_GCM_LESS = 0x0201, - CELL_GCM_EQUAL = 0x0202, - CELL_GCM_LEQUAL = 0x0203, - CELL_GCM_GREATER = 0x0204, - CELL_GCM_NOTEQUAL = 0x0205, - CELL_GCM_GEQUAL = 0x0206, - CELL_GCM_ALWAYS = 0x0207, - - // Stencil Op - CELL_GCM_KEEP = 0x1E00, - CELL_GCM_REPLACE = 0x1E01, - CELL_GCM_INCR = 0x1E02, - CELL_GCM_DECR = 0x1E03, - CELL_GCM_INCR_WRAP = 0x8507, - CELL_GCM_DECR_WRAP = 0x8508, - - // Front Face - CELL_GCM_FRONT = 0x0404, - CELL_GCM_BACK = 0x0405, - CELL_GCM_FRONT_AND_BACK = 0x0408, - - // Cull Face - CELL_GCM_CW = 0x0900, - CELL_GCM_CCW = 0x0901, - - // Texture Filter - CELL_GCM_TEXTURE_NEAREST = 1, - CELL_GCM_TEXTURE_LINEAR = 2, - CELL_GCM_TEXTURE_NEAREST_NEAREST = 3, - CELL_GCM_TEXTURE_LINEAR_NEAREST = 4, - CELL_GCM_TEXTURE_NEAREST_LINEAR = 5, - CELL_GCM_TEXTURE_LINEAR_LINEAR = 6, - CELL_GCM_TEXTURE_CONVOLUTION_MIN = 7, }; // GCM Surface @@ -258,19 +179,242 @@ enum }; -// GCM Primitive enum { - CELL_GCM_PRIMITIVE_POINTS = 1, - CELL_GCM_PRIMITIVE_LINES = 2, - CELL_GCM_PRIMITIVE_LINE_LOOP = 3, - CELL_GCM_PRIMITIVE_LINE_STRIP = 4, - CELL_GCM_PRIMITIVE_TRIANGLES = 5, - CELL_GCM_PRIMITIVE_TRIANGLE_STRIP = 6, - CELL_GCM_PRIMITIVE_TRIANGLE_FAN = 7, - CELL_GCM_PRIMITIVE_QUADS = 8, - CELL_GCM_PRIMITIVE_QUAD_STRIP = 9, - CELL_GCM_PRIMITIVE_POLYGON = 10, + CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL = 0, + CELL_GCM_TEXTURE_UNSIGNED_REMAP_BIASED = 1, + + CELL_GCM_TEXTURE_SIGNED_REMAP_NORMAL = 0x0, + CELL_GCM_TEXTURE_SIGNED_REMAP_CLAMPED = 0x3, + + CELL_GCM_TEXTURE_ZFUNC_NEVER = 0, + CELL_GCM_TEXTURE_ZFUNC_LESS = 1, + CELL_GCM_TEXTURE_ZFUNC_EQUAL = 2, + CELL_GCM_TEXTURE_ZFUNC_LEQUAL = 3, + CELL_GCM_TEXTURE_ZFUNC_GREATER = 4, + CELL_GCM_TEXTURE_ZFUNC_NOTEQUAL = 5, + CELL_GCM_TEXTURE_ZFUNC_GEQUAL = 6, + CELL_GCM_TEXTURE_ZFUNC_ALWAYS = 7, + + CELL_GCM_TEXTURE_GAMMA_R = 1 << 0, + CELL_GCM_TEXTURE_GAMMA_G = 1 << 1, + CELL_GCM_TEXTURE_GAMMA_B = 1 << 2, + CELL_GCM_TEXTURE_GAMMA_A = 1 << 3, + + CELL_GCM_TEXTURE_ANISO_SPREAD_0_50_TEXEL = 0x0, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_00_TEXEL = 0x1, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_125_TEXEL = 0x2, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_25_TEXEL = 0x3, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_375_TEXEL = 0x4, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_50_TEXEL = 0x5, + CELL_GCM_TEXTURE_ANISO_SPREAD_1_75_TEXEL = 0x6, + CELL_GCM_TEXTURE_ANISO_SPREAD_2_00_TEXEL = 0x7, + + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_U = 1 << 0, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_V = 1 << 1, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_P = 1 << 2, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX0_Q = 1 << 3, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_U = 1 << 4, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_V = 1 << 5, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_P = 1 << 6, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX1_Q = 1 << 7, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_U = 1 << 8, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_V = 1 << 9, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_P = 1 << 10, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX2_Q = 1 << 11, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_U = 1 << 12, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_V = 1 << 13, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_P = 1 << 14, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX3_Q = 1 << 15, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_U = 1 << 16, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_V = 1 << 17, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_P = 1 << 18, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX4_Q = 1 << 19, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_U = 1 << 20, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_V = 1 << 21, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_P = 1 << 22, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX5_Q = 1 << 23, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_U = 1 << 24, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_V = 1 << 25, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_P = 1 << 26, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX6_Q = 1 << 27, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_U = 1 << 28, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_V = 1 << 29, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_P = 1 << 30, + CELL_GCM_TEXTURE_CYLINDRICAL_WRAP_ENABLE_TEX7_Q = 1 << 31, + + // Texture Filter + CELL_GCM_TEXTURE_NEAREST = 1, + CELL_GCM_TEXTURE_LINEAR = 2, + CELL_GCM_TEXTURE_NEAREST_NEAREST = 3, + CELL_GCM_TEXTURE_LINEAR_NEAREST = 4, + CELL_GCM_TEXTURE_NEAREST_LINEAR = 5, + CELL_GCM_TEXTURE_LINEAR_LINEAR = 6, + CELL_GCM_TEXTURE_CONVOLUTION_MIN = 7, + + CELL_GCM_PRIMITIVE_POINTS = 1, + CELL_GCM_PRIMITIVE_LINES = 2, + CELL_GCM_PRIMITIVE_LINE_LOOP = 3, + CELL_GCM_PRIMITIVE_LINE_STRIP = 4, + CELL_GCM_PRIMITIVE_TRIANGLES = 5, + CELL_GCM_PRIMITIVE_TRIANGLE_STRIP = 6, + CELL_GCM_PRIMITIVE_TRIANGLE_FAN = 7, + CELL_GCM_PRIMITIVE_QUADS = 8, + CELL_GCM_PRIMITIVE_QUAD_STRIP = 9, + CELL_GCM_PRIMITIVE_POLYGON = 10, + + CELL_GCM_COLOR_MASK_B = 1 << 0, + CELL_GCM_COLOR_MASK_G = 1 << 8, + CELL_GCM_COLOR_MASK_R = 1 << 16, + CELL_GCM_COLOR_MASK_A = 1 << 24, + + CELL_GCM_COLOR_MASK_MRT1_A = 1 << 4, + CELL_GCM_COLOR_MASK_MRT1_R = 1 << 5, + CELL_GCM_COLOR_MASK_MRT1_G = 1 << 6, + CELL_GCM_COLOR_MASK_MRT1_B = 1 << 7, + CELL_GCM_COLOR_MASK_MRT2_A = 1 << 8, + CELL_GCM_COLOR_MASK_MRT2_R = 1 << 9, + CELL_GCM_COLOR_MASK_MRT2_G = 1 << 10, + CELL_GCM_COLOR_MASK_MRT2_B = 1 << 11, + CELL_GCM_COLOR_MASK_MRT3_A = 1 << 12, + CELL_GCM_COLOR_MASK_MRT3_R = 1 << 13, + CELL_GCM_COLOR_MASK_MRT3_G = 1 << 14, + CELL_GCM_COLOR_MASK_MRT3_B = 1 << 15, + + CELL_GCM_NEVER = 0x0200, + CELL_GCM_LESS = 0x0201, + CELL_GCM_EQUAL = 0x0202, + CELL_GCM_LEQUAL = 0x0203, + CELL_GCM_GREATER = 0x0204, + CELL_GCM_NOTEQUAL = 0x0205, + CELL_GCM_GEQUAL = 0x0206, + CELL_GCM_ALWAYS = 0x0207, + + CELL_GCM_ZERO = 0, + CELL_GCM_ONE = 1, + CELL_GCM_SRC_COLOR = 0x0300, + CELL_GCM_ONE_MINUS_SRC_COLOR = 0x0301, + CELL_GCM_SRC_ALPHA = 0x0302, + CELL_GCM_ONE_MINUS_SRC_ALPHA = 0x0303, + CELL_GCM_DST_ALPHA = 0x0304, + CELL_GCM_ONE_MINUS_DST_ALPHA = 0x0305, + CELL_GCM_DST_COLOR = 0x0306, + CELL_GCM_ONE_MINUS_DST_COLOR = 0x0307, + CELL_GCM_SRC_ALPHA_SATURATE = 0x0308, + CELL_GCM_CONSTANT_COLOR = 0x8001, + CELL_GCM_ONE_MINUS_CONSTANT_COLOR = 0x8002, + CELL_GCM_CONSTANT_ALPHA = 0x8003, + CELL_GCM_ONE_MINUS_CONSTANT_ALPHA = 0x8004, + + CELL_GCM_FUNC_ADD = 0x8006, + CELL_GCM_MIN = 0x8007, + CELL_GCM_MAX = 0x8008, + CELL_GCM_FUNC_SUBTRACT = 0x800A, + CELL_GCM_FUNC_REVERSE_SUBTRACT = 0x800B, + CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED = 0x0000F005, + CELL_GCM_FUNC_ADD_SIGNED = 0x0000F006, + CELL_GCM_FUNC_REVERSE_ADD_SIGNED = 0x0000F007, + + CELL_GCM_FRONT = 0x0404, + CELL_GCM_BACK = 0x0405, + CELL_GCM_FRONT_AND_BACK = 0x0408, + + CELL_GCM_CW = 0x0900, + CELL_GCM_CCW = 0x0901, + + CELL_GCM_CLEAR = 0x1500, + CELL_GCM_AND = 0x1501, + CELL_GCM_AND_REVERSE = 0x1502, + CELL_GCM_COPY = 0x1503, + CELL_GCM_AND_INVERTED = 0x1504, + CELL_GCM_NOOP = 0x1505, + CELL_GCM_XOR = 0x1506, + CELL_GCM_OR = 0x1507, + CELL_GCM_NOR = 0x1508, + CELL_GCM_EQUIV = 0x1509, + CELL_GCM_INVERT = 0x150A, + CELL_GCM_OR_REVERSE = 0x150B, + CELL_GCM_COPY_INVERTED = 0x150C, + CELL_GCM_OR_INVERTED = 0x150D, + CELL_GCM_NAND = 0x150E, + CELL_GCM_SET = 0x150F, + + CELL_GCM_KEEP = 0x1E00, + CELL_GCM_REPLACE = 0x1E01, + CELL_GCM_INCR = 0x1E02, + CELL_GCM_DECR = 0x1E03, + CELL_GCM_INCR_WRAP = 0x8507, + CELL_GCM_DECR_WRAP = 0x8508, + + CELL_GCM_TRANSFER_LOCAL_TO_LOCAL = 0, + CELL_GCM_TRANSFER_MAIN_TO_LOCAL = 1, + CELL_GCM_TRANSFER_LOCAL_TO_MAIN = 2, + CELL_GCM_TRANSFER_MAIN_TO_MAIN = 3, + + CELL_GCM_INVALIDATE_TEXTURE = 1, + CELL_GCM_INVALIDATE_VERTEX_TEXTURE = 2, + + CELL_GCM_COMPMODE_DISABLED = 0, + CELL_GCM_COMPMODE_C32_2X1 = 7, + CELL_GCM_COMPMODE_C32_2X2 = 8, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL = 9, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_REG = 10, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_REGULAR = 10, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_DIAGONAL = 11, + CELL_GCM_COMPMODE_Z32_SEPSTENCIL_ROTATED = 12, + + CELL_GCM_ZCULL_Z16 = 1, + CELL_GCM_ZCULL_Z24S8 = 2, + CELL_GCM_ZCULL_MSB = 0, + CELL_GCM_ZCULL_LONES = 1, + CELL_GCM_ZCULL_LESS = 0, + CELL_GCM_ZCULL_GREATER = 1, + + CELL_GCM_SCULL_SFUNC_NEVER = 0, + CELL_GCM_SCULL_SFUNC_LESS = 1, + CELL_GCM_SCULL_SFUNC_EQUAL = 2, + CELL_GCM_SCULL_SFUNC_LEQUAL = 3, + CELL_GCM_SCULL_SFUNC_GREATER = 4, + CELL_GCM_SCULL_SFUNC_NOTEQUAL = 5, + CELL_GCM_SCULL_SFUNC_GEQUAL = 6, + CELL_GCM_SCULL_SFUNC_ALWAYS = 7, + + CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE = 1 << 0, + CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR = 1 << 1, + CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE = 1 << 2, + CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR = 1 << 3, + CELL_GCM_ATTRIB_OUTPUT_MASK_FOG = 1 << 4, + CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE = 1 << 5, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 = 1 << 6, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 = 1 << 7, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 = 1 << 8, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 = 1 << 9, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 = 1 << 10, + CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 = 1 << 11, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 = 1 << 12, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 = 1 << 13, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 = 1 << 14, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 = 1 << 15, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 = 1 << 16, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 = 1 << 17, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 = 1 << 18, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 = 1 << 19, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << 20, + CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << 21, + + CELL_GCM_FOG_MODE_LINEAR = 0x2601, + CELL_GCM_FOG_MODE_EXP = 0x0800, + CELL_GCM_FOG_MODE_EXP2 = 0x0801, + CELL_GCM_FOG_MODE_EXP_ABS = 0x0802, + CELL_GCM_FOG_MODE_EXP2_ABS = 0x0803, + CELL_GCM_FOG_MODE_LINEAR_ABS = 0x0804, + + CELL_GCM_POLYGON_MODE_POINT = 0x1B00, + CELL_GCM_POLYGON_MODE_LINE = 0x1B01, + CELL_GCM_POLYGON_MODE_FILL = 0x1B02, + + CELL_GCM_TRUE = 1, + CELL_GCM_FALSE = 0 }; // GCM Reports @@ -295,14 +439,6 @@ enum CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F, }; -// User Clip Values -enum -{ - CELL_GCM_USER_CLIP_PLANE_DISABLE = 0, - CELL_GCM_USER_CLIP_PLANE_ENABLE_LT = 1, - CELL_GCM_USER_CLIP_PLANE_ENABLE_GE = 2, -}; - struct CellGcmControl { atomic_be_t put; @@ -362,9 +498,9 @@ struct CellGcmSurface struct CellGcmReportData { - u64 timer; - u32 value; - u32 padding; + be_t timer; + be_t value; + be_t padding; }; struct CellGcmZcullInfo @@ -413,7 +549,7 @@ struct GcmZcullInfo memset(this, 0, sizeof(*this)); } - CellGcmZcullInfo Pack() + CellGcmZcullInfo pack() const { CellGcmZcullInfo ret; @@ -430,13 +566,13 @@ struct GcmZcullInfo struct GcmTileInfo { - u8 location; + u32 location; u32 offset; u32 size; u32 pitch; - u8 comp; - u16 base; - u8 bank; + u32 comp; + u32 base; + u32 bank; bool binded; GcmTileInfo() @@ -444,7 +580,7 @@ struct GcmTileInfo memset(this, 0, sizeof(*this)); } - CellGcmTileInfo Pack() + CellGcmTileInfo pack() const { CellGcmTileInfo ret; @@ -460,1012 +596,1052 @@ struct GcmTileInfo enum { // NV40_CHANNEL_DMA (NV406E) - NV406E_SET_REFERENCE = 0x00000050, - NV406E_SET_CONTEXT_DMA_SEMAPHORE = 0x00000060, - NV406E_SEMAPHORE_OFFSET = 0x00000064, - NV406E_SEMAPHORE_ACQUIRE = 0x00000068, - NV406E_SEMAPHORE_RELEASE = 0x0000006c, + NV406E_SET_REFERENCE = 0x00000050 >> 2, + NV406E_SET_CONTEXT_DMA_SEMAPHORE = 0x00000060 >> 2, + NV406E_SEMAPHORE_OFFSET = 0x00000064 >> 2, + NV406E_SEMAPHORE_ACQUIRE = 0x00000068 >> 2, + NV406E_SEMAPHORE_RELEASE = 0x0000006c >> 2, // NV40_CURIE_PRIMITIVE (NV4097) - NV4097_SET_OBJECT = 0x00000000, - NV4097_NO_OPERATION = 0x00000100, - NV4097_NOTIFY = 0x00000104, - NV4097_WAIT_FOR_IDLE = 0x00000110, - NV4097_PM_TRIGGER = 0x00000140, - NV4097_SET_CONTEXT_DMA_NOTIFIES = 0x00000180, - NV4097_SET_CONTEXT_DMA_A = 0x00000184, - NV4097_SET_CONTEXT_DMA_B = 0x00000188, - NV4097_SET_CONTEXT_DMA_COLOR_B = 0x0000018c, - NV4097_SET_CONTEXT_DMA_STATE = 0x00000190, - NV4097_SET_CONTEXT_DMA_COLOR_A = 0x00000194, - NV4097_SET_CONTEXT_DMA_ZETA = 0x00000198, - NV4097_SET_CONTEXT_DMA_VERTEX_A = 0x0000019c, - NV4097_SET_CONTEXT_DMA_VERTEX_B = 0x000001a0, - NV4097_SET_CONTEXT_DMA_SEMAPHORE = 0x000001a4, - NV4097_SET_CONTEXT_DMA_REPORT = 0x000001a8, - NV4097_SET_CONTEXT_DMA_CLIP_ID = 0x000001ac, - NV4097_SET_CONTEXT_DMA_CULL_DATA = 0x000001b0, - NV4097_SET_CONTEXT_DMA_COLOR_C = 0x000001b4, - NV4097_SET_CONTEXT_DMA_COLOR_D = 0x000001b8, - NV4097_SET_SURFACE_CLIP_HORIZONTAL = 0x00000200, - NV4097_SET_SURFACE_CLIP_VERTICAL = 0x00000204, - NV4097_SET_SURFACE_FORMAT = 0x00000208, - NV4097_SET_SURFACE_PITCH_A = 0x0000020c, - NV4097_SET_SURFACE_COLOR_AOFFSET = 0x00000210, - NV4097_SET_SURFACE_ZETA_OFFSET = 0x00000214, - NV4097_SET_SURFACE_COLOR_BOFFSET = 0x00000218, - NV4097_SET_SURFACE_PITCH_B = 0x0000021c, - NV4097_SET_SURFACE_COLOR_TARGET = 0x00000220, - NV4097_SET_SURFACE_PITCH_Z = 0x0000022c, - NV4097_INVALIDATE_ZCULL = 0x00000234, - NV4097_SET_CYLINDRICAL_WRAP = 0x00000238, - NV4097_SET_CYLINDRICAL_WRAP1 = 0x0000023c, - NV4097_SET_SURFACE_PITCH_C = 0x00000280, - NV4097_SET_SURFACE_PITCH_D = 0x00000284, - NV4097_SET_SURFACE_COLOR_COFFSET = 0x00000288, - NV4097_SET_SURFACE_COLOR_DOFFSET = 0x0000028c, - NV4097_SET_WINDOW_OFFSET = 0x000002b8, - NV4097_SET_WINDOW_CLIP_TYPE = 0x000002bc, - NV4097_SET_WINDOW_CLIP_HORIZONTAL = 0x000002c0, - NV4097_SET_WINDOW_CLIP_VERTICAL = 0x000002c4, - NV4097_SET_DITHER_ENABLE = 0x00000300, - NV4097_SET_ALPHA_TEST_ENABLE = 0x00000304, - NV4097_SET_ALPHA_FUNC = 0x00000308, - NV4097_SET_ALPHA_REF = 0x0000030c, - NV4097_SET_BLEND_ENABLE = 0x00000310, - NV4097_SET_BLEND_FUNC_SFACTOR = 0x00000314, - NV4097_SET_BLEND_FUNC_DFACTOR = 0x00000318, - NV4097_SET_BLEND_COLOR = 0x0000031c, - NV4097_SET_BLEND_EQUATION = 0x00000320, - NV4097_SET_COLOR_MASK = 0x00000324, - NV4097_SET_STENCIL_TEST_ENABLE = 0x00000328, - NV4097_SET_STENCIL_MASK = 0x0000032c, - NV4097_SET_STENCIL_FUNC = 0x00000330, - NV4097_SET_STENCIL_FUNC_REF = 0x00000334, - NV4097_SET_STENCIL_FUNC_MASK = 0x00000338, - NV4097_SET_STENCIL_OP_FAIL = 0x0000033c, - NV4097_SET_STENCIL_OP_ZFAIL = 0x00000340, - NV4097_SET_STENCIL_OP_ZPASS = 0x00000344, - NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE = 0x00000348, - NV4097_SET_BACK_STENCIL_MASK = 0x0000034c, - NV4097_SET_BACK_STENCIL_FUNC = 0x00000350, - NV4097_SET_BACK_STENCIL_FUNC_REF = 0x00000354, - NV4097_SET_BACK_STENCIL_FUNC_MASK = 0x00000358, - NV4097_SET_BACK_STENCIL_OP_FAIL = 0x0000035c, - NV4097_SET_BACK_STENCIL_OP_ZFAIL = 0x00000360, - NV4097_SET_BACK_STENCIL_OP_ZPASS = 0x00000364, - NV4097_SET_SHADE_MODE = 0x00000368, - NV4097_SET_BLEND_ENABLE_MRT = 0x0000036c, - NV4097_SET_COLOR_MASK_MRT = 0x00000370, - NV4097_SET_LOGIC_OP_ENABLE = 0x00000374, - NV4097_SET_LOGIC_OP = 0x00000378, - NV4097_SET_BLEND_COLOR2 = 0x0000037c, - NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE = 0x00000380, - NV4097_SET_DEPTH_BOUNDS_MIN = 0x00000384, - NV4097_SET_DEPTH_BOUNDS_MAX = 0x00000388, - NV4097_SET_CLIP_MIN = 0x00000394, - NV4097_SET_CLIP_MAX = 0x00000398, - NV4097_SET_CONTROL0 = 0x000003b0, - NV4097_SET_LINE_WIDTH = 0x000003b8, - NV4097_SET_LINE_SMOOTH_ENABLE = 0x000003bc, - NV4097_SET_ANISO_SPREAD = 0x000003c0, - NV4097_SET_SCISSOR_HORIZONTAL = 0x000008c0, - NV4097_SET_SCISSOR_VERTICAL = 0x000008c4, - NV4097_SET_FOG_MODE = 0x000008cc, - NV4097_SET_FOG_PARAMS = 0x000008d0, - NV4097_SET_SHADER_PROGRAM = 0x000008e4, - NV4097_SET_VERTEX_TEXTURE_OFFSET = 0x00000900, - NV4097_SET_VERTEX_TEXTURE_FORMAT = 0x00000904, - NV4097_SET_VERTEX_TEXTURE_ADDRESS = 0x00000908, - NV4097_SET_VERTEX_TEXTURE_CONTROL0 = 0x0000090c, - NV4097_SET_VERTEX_TEXTURE_CONTROL3 = 0x00000910, - NV4097_SET_VERTEX_TEXTURE_FILTER = 0x00000914, - NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT = 0x00000918, - NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR = 0x0000091c, - NV4097_SET_VIEWPORT_HORIZONTAL = 0x00000a00, - NV4097_SET_VIEWPORT_VERTICAL = 0x00000a04, - NV4097_SET_POINT_CENTER_MODE = 0x00000a0c, - NV4097_ZCULL_SYNC = 0x00000a1c, - NV4097_SET_VIEWPORT_OFFSET = 0x00000a20, - NV4097_SET_VIEWPORT_SCALE = 0x00000a30, - NV4097_SET_POLY_OFFSET_POINT_ENABLE = 0x00000a60, - NV4097_SET_POLY_OFFSET_LINE_ENABLE = 0x00000a64, - NV4097_SET_POLY_OFFSET_FILL_ENABLE = 0x00000a68, - NV4097_SET_DEPTH_FUNC = 0x00000a6c, - NV4097_SET_DEPTH_MASK = 0x00000a70, - NV4097_SET_DEPTH_TEST_ENABLE = 0x00000a74, - NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR = 0x00000a78, - NV4097_SET_POLYGON_OFFSET_BIAS = 0x00000a7c, - NV4097_SET_VERTEX_DATA_SCALED4S_M = 0x00000a80, - NV4097_SET_TEXTURE_CONTROL2 = 0x00000b00, - NV4097_SET_TEX_COORD_CONTROL = 0x00000b40, - NV4097_SET_TRANSFORM_PROGRAM = 0x00000b80, - NV4097_SET_SPECULAR_ENABLE = 0x00001428, - NV4097_SET_TWO_SIDE_LIGHT_EN = 0x0000142c, - NV4097_CLEAR_ZCULL_SURFACE = 0x00001438, - NV4097_SET_PERFORMANCE_PARAMS = 0x00001450, - NV4097_SET_FLAT_SHADE_OP = 0x00001454, - NV4097_SET_EDGE_FLAG = 0x0000145c, - NV4097_SET_USER_CLIP_PLANE_CONTROL = 0x00001478, - NV4097_SET_POLYGON_STIPPLE = 0x0000147c, - NV4097_SET_POLYGON_STIPPLE_PATTERN = 0x00001480, - NV4097_SET_VERTEX_DATA3F_M = 0x00001500, - NV4097_SET_VERTEX_DATA_ARRAY_OFFSET = 0x00001680, - NV4097_INVALIDATE_VERTEX_CACHE_FILE = 0x00001710, - NV4097_INVALIDATE_VERTEX_FILE = 0x00001714, - NV4097_PIPE_NOP = 0x00001718, - NV4097_SET_VERTEX_DATA_BASE_OFFSET = 0x00001738, - NV4097_SET_VERTEX_DATA_BASE_INDEX = 0x0000173c, - NV4097_SET_VERTEX_DATA_ARRAY_FORMAT = 0x00001740, - NV4097_CLEAR_REPORT_VALUE = 0x000017c8, - NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE = 0x000017cc, - NV4097_GET_REPORT = 0x00001800, - NV4097_SET_ZCULL_STATS_ENABLE = 0x00001804, - NV4097_SET_BEGIN_END = 0x00001808, - NV4097_ARRAY_ELEMENT16 = 0x0000180c, - NV4097_ARRAY_ELEMENT32 = 0x00001810, - NV4097_DRAW_ARRAYS = 0x00001814, - NV4097_INLINE_ARRAY = 0x00001818, - NV4097_SET_INDEX_ARRAY_ADDRESS = 0x0000181c, - NV4097_SET_INDEX_ARRAY_DMA = 0x00001820, - NV4097_DRAW_INDEX_ARRAY = 0x00001824, - NV4097_SET_FRONT_POLYGON_MODE = 0x00001828, - NV4097_SET_BACK_POLYGON_MODE = 0x0000182c, - NV4097_SET_CULL_FACE = 0x00001830, - NV4097_SET_FRONT_FACE = 0x00001834, - NV4097_SET_POLY_SMOOTH_ENABLE = 0x00001838, - NV4097_SET_CULL_FACE_ENABLE = 0x0000183c, - NV4097_SET_TEXTURE_CONTROL3 = 0x00001840, - NV4097_SET_VERTEX_DATA2F_M = 0x00001880, - NV4097_SET_VERTEX_DATA2S_M = 0x00001900, - NV4097_SET_VERTEX_DATA4UB_M = 0x00001940, - NV4097_SET_VERTEX_DATA4S_M = 0x00001980, - NV4097_SET_TEXTURE_OFFSET = 0x00001a00, - NV4097_SET_TEXTURE_FORMAT = 0x00001a04, - NV4097_SET_TEXTURE_ADDRESS = 0x00001a08, - NV4097_SET_TEXTURE_CONTROL0 = 0x00001a0c, - NV4097_SET_TEXTURE_CONTROL1 = 0x00001a10, - NV4097_SET_TEXTURE_FILTER = 0x00001a14, - NV4097_SET_TEXTURE_IMAGE_RECT = 0x00001a18, - NV4097_SET_TEXTURE_BORDER_COLOR = 0x00001a1c, - NV4097_SET_VERTEX_DATA4F_M = 0x00001c00, - NV4097_SET_COLOR_KEY_COLOR = 0x00001d00, - NV4097_SET_SHADER_CONTROL = 0x00001d60, - NV4097_SET_INDEXED_CONSTANT_READ_LIMITS = 0x00001d64, - NV4097_SET_SEMAPHORE_OFFSET = 0x00001d6c, - NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE = 0x00001d70, - NV4097_TEXTURE_READ_SEMAPHORE_RELEASE = 0x00001d74, - NV4097_SET_ZMIN_MAX_CONTROL = 0x00001d78, - NV4097_SET_ANTI_ALIASING_CONTROL = 0x00001d7c, - NV4097_SET_SURFACE_COMPRESSION = 0x00001d80, - NV4097_SET_ZCULL_EN = 0x00001d84, - NV4097_SET_SHADER_WINDOW = 0x00001d88, - NV4097_SET_ZSTENCIL_CLEAR_VALUE = 0x00001d8c, - NV4097_SET_COLOR_CLEAR_VALUE = 0x00001d90, - NV4097_CLEAR_SURFACE = 0x00001d94, - NV4097_SET_CLEAR_RECT_HORIZONTAL = 0x00001d98, - NV4097_SET_CLEAR_RECT_VERTICAL = 0x00001d9c, - NV4097_SET_CLIP_ID_TEST_ENABLE = 0x00001da4, - NV4097_SET_RESTART_INDEX_ENABLE = 0x00001dac, - NV4097_SET_RESTART_INDEX = 0x00001db0, - NV4097_SET_LINE_STIPPLE = 0x00001db4, - NV4097_SET_LINE_STIPPLE_PATTERN = 0x00001db8, - NV4097_SET_VERTEX_DATA1F_M = 0x00001e40, - NV4097_SET_TRANSFORM_EXECUTION_MODE = 0x00001e94, - NV4097_SET_RENDER_ENABLE = 0x00001e98, - NV4097_SET_TRANSFORM_PROGRAM_LOAD = 0x00001e9c, - NV4097_SET_TRANSFORM_PROGRAM_START = 0x00001ea0, - NV4097_SET_ZCULL_CONTROL0 = 0x00001ea4, - NV4097_SET_ZCULL_CONTROL1 = 0x00001ea8, - NV4097_SET_SCULL_CONTROL = 0x00001eac, - NV4097_SET_POINT_SIZE = 0x00001ee0, - NV4097_SET_POINT_PARAMS_ENABLE = 0x00001ee4, - NV4097_SET_POINT_SPRITE_CONTROL = 0x00001ee8, - NV4097_SET_TRANSFORM_TIMEOUT = 0x00001ef8, - NV4097_SET_TRANSFORM_CONSTANT_LOAD = 0x00001efc, - NV4097_SET_TRANSFORM_CONSTANT = 0x00001f00, - NV4097_SET_FREQUENCY_DIVIDER_OPERATION = 0x00001fc0, - NV4097_SET_ATTRIB_COLOR = 0x00001fc4, - NV4097_SET_ATTRIB_TEX_COORD = 0x00001fc8, - NV4097_SET_ATTRIB_TEX_COORD_EX = 0x00001fcc, - NV4097_SET_ATTRIB_UCLIP0 = 0x00001fd0, - NV4097_SET_ATTRIB_UCLIP1 = 0x00001fd4, - NV4097_INVALIDATE_L2 = 0x00001fd8, - NV4097_SET_REDUCE_DST_COLOR = 0x00001fe0, - NV4097_SET_NO_PARANOID_TEXTURE_FETCHES = 0x00001fe8, - NV4097_SET_SHADER_PACKER = 0x00001fec, - NV4097_SET_VERTEX_ATTRIB_INPUT_MASK = 0x00001ff0, - NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK = 0x00001ff4, - NV4097_SET_TRANSFORM_BRANCH_BITS = 0x00001ff8, + NV4097_SET_OBJECT = 0x00000000 >> 2, + NV4097_NO_OPERATION = 0x00000100 >> 2, + NV4097_NOTIFY = 0x00000104 >> 2, + NV4097_WAIT_FOR_IDLE = 0x00000110 >> 2, + NV4097_PM_TRIGGER = 0x00000140 >> 2, + NV4097_SET_CONTEXT_DMA_NOTIFIES = 0x00000180 >> 2, + NV4097_SET_CONTEXT_DMA_A = 0x00000184 >> 2, + NV4097_SET_CONTEXT_DMA_B = 0x00000188 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_B = 0x0000018c >> 2, + NV4097_SET_CONTEXT_DMA_STATE = 0x00000190 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_A = 0x00000194 >> 2, + NV4097_SET_CONTEXT_DMA_ZETA = 0x00000198 >> 2, + NV4097_SET_CONTEXT_DMA_VERTEX_A = 0x0000019c >> 2, + NV4097_SET_CONTEXT_DMA_VERTEX_B = 0x000001a0 >> 2, + NV4097_SET_CONTEXT_DMA_SEMAPHORE = 0x000001a4 >> 2, + NV4097_SET_CONTEXT_DMA_REPORT = 0x000001a8 >> 2, + NV4097_SET_CONTEXT_DMA_CLIP_ID = 0x000001ac >> 2, + NV4097_SET_CONTEXT_DMA_CULL_DATA = 0x000001b0 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_C = 0x000001b4 >> 2, + NV4097_SET_CONTEXT_DMA_COLOR_D = 0x000001b8 >> 2, + NV4097_SET_SURFACE_CLIP_HORIZONTAL = 0x00000200 >> 2, + NV4097_SET_SURFACE_CLIP_VERTICAL = 0x00000204 >> 2, + NV4097_SET_SURFACE_FORMAT = 0x00000208 >> 2, + NV4097_SET_SURFACE_PITCH_A = 0x0000020c >> 2, + NV4097_SET_SURFACE_COLOR_AOFFSET = 0x00000210 >> 2, + NV4097_SET_SURFACE_ZETA_OFFSET = 0x00000214 >> 2, + NV4097_SET_SURFACE_COLOR_BOFFSET = 0x00000218 >> 2, + NV4097_SET_SURFACE_PITCH_B = 0x0000021c >> 2, + NV4097_SET_SURFACE_COLOR_TARGET = 0x00000220 >> 2, + NV4097_SET_SURFACE_PITCH_Z = 0x0000022c >> 2, + NV4097_INVALIDATE_ZCULL = 0x00000234 >> 2, + NV4097_SET_CYLINDRICAL_WRAP = 0x00000238 >> 2, + NV4097_SET_CYLINDRICAL_WRAP1 = 0x0000023c >> 2, + NV4097_SET_SURFACE_PITCH_C = 0x00000280 >> 2, + NV4097_SET_SURFACE_PITCH_D = 0x00000284 >> 2, + NV4097_SET_SURFACE_COLOR_COFFSET = 0x00000288 >> 2, + NV4097_SET_SURFACE_COLOR_DOFFSET = 0x0000028c >> 2, + NV4097_SET_WINDOW_OFFSET = 0x000002b8 >> 2, + NV4097_SET_WINDOW_CLIP_TYPE = 0x000002bc >> 2, + NV4097_SET_WINDOW_CLIP_HORIZONTAL = 0x000002c0 >> 2, + NV4097_SET_WINDOW_CLIP_VERTICAL = 0x000002c4 >> 2, + NV4097_SET_DITHER_ENABLE = 0x00000300 >> 2, + NV4097_SET_ALPHA_TEST_ENABLE = 0x00000304 >> 2, + NV4097_SET_ALPHA_FUNC = 0x00000308 >> 2, + NV4097_SET_ALPHA_REF = 0x0000030c >> 2, + NV4097_SET_BLEND_ENABLE = 0x00000310 >> 2, + NV4097_SET_BLEND_FUNC_SFACTOR = 0x00000314 >> 2, + NV4097_SET_BLEND_FUNC_DFACTOR = 0x00000318 >> 2, + NV4097_SET_BLEND_COLOR = 0x0000031c >> 2, + NV4097_SET_BLEND_EQUATION = 0x00000320 >> 2, + NV4097_SET_COLOR_MASK = 0x00000324 >> 2, + NV4097_SET_STENCIL_TEST_ENABLE = 0x00000328 >> 2, + NV4097_SET_STENCIL_MASK = 0x0000032c >> 2, + NV4097_SET_STENCIL_FUNC = 0x00000330 >> 2, + NV4097_SET_STENCIL_FUNC_REF = 0x00000334 >> 2, + NV4097_SET_STENCIL_FUNC_MASK = 0x00000338 >> 2, + NV4097_SET_STENCIL_OP_FAIL = 0x0000033c >> 2, + NV4097_SET_STENCIL_OP_ZFAIL = 0x00000340 >> 2, + NV4097_SET_STENCIL_OP_ZPASS = 0x00000344 >> 2, + NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE = 0x00000348 >> 2, + NV4097_SET_BACK_STENCIL_MASK = 0x0000034c >> 2, + NV4097_SET_BACK_STENCIL_FUNC = 0x00000350 >> 2, + NV4097_SET_BACK_STENCIL_FUNC_REF = 0x00000354 >> 2, + NV4097_SET_BACK_STENCIL_FUNC_MASK = 0x00000358 >> 2, + NV4097_SET_BACK_STENCIL_OP_FAIL = 0x0000035c >> 2, + NV4097_SET_BACK_STENCIL_OP_ZFAIL = 0x00000360 >> 2, + NV4097_SET_BACK_STENCIL_OP_ZPASS = 0x00000364 >> 2, + NV4097_SET_SHADE_MODE = 0x00000368 >> 2, + NV4097_SET_BLEND_ENABLE_MRT = 0x0000036c >> 2, + NV4097_SET_COLOR_MASK_MRT = 0x00000370 >> 2, + NV4097_SET_LOGIC_OP_ENABLE = 0x00000374 >> 2, + NV4097_SET_LOGIC_OP = 0x00000378 >> 2, + NV4097_SET_BLEND_COLOR2 = 0x0000037c >> 2, + NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE = 0x00000380 >> 2, + NV4097_SET_DEPTH_BOUNDS_MIN = 0x00000384 >> 2, + NV4097_SET_DEPTH_BOUNDS_MAX = 0x00000388 >> 2, + NV4097_SET_CLIP_MIN = 0x00000394 >> 2, + NV4097_SET_CLIP_MAX = 0x00000398 >> 2, + NV4097_SET_CONTROL0 = 0x000003b0 >> 2, + NV4097_SET_LINE_WIDTH = 0x000003b8 >> 2, + NV4097_SET_LINE_SMOOTH_ENABLE = 0x000003bc >> 2, + NV4097_SET_ANISO_SPREAD = 0x000003c0 >> 2, + NV4097_SET_SCISSOR_HORIZONTAL = 0x000008c0 >> 2, + NV4097_SET_SCISSOR_VERTICAL = 0x000008c4 >> 2, + NV4097_SET_FOG_MODE = 0x000008cc >> 2, + NV4097_SET_FOG_PARAMS = 0x000008d0 >> 2, + NV4097_SET_SHADER_PROGRAM = 0x000008e4 >> 2, + NV4097_SET_VERTEX_TEXTURE_OFFSET = 0x00000900 >> 2, + NV4097_SET_VERTEX_TEXTURE_FORMAT = 0x00000904 >> 2, + NV4097_SET_VERTEX_TEXTURE_ADDRESS = 0x00000908 >> 2, + NV4097_SET_VERTEX_TEXTURE_CONTROL0 = 0x0000090c >> 2, + NV4097_SET_VERTEX_TEXTURE_CONTROL3 = 0x00000910 >> 2, + NV4097_SET_VERTEX_TEXTURE_FILTER = 0x00000914 >> 2, + NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT = 0x00000918 >> 2, + NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR = 0x0000091c >> 2, + NV4097_SET_VIEWPORT_HORIZONTAL = 0x00000a00 >> 2, + NV4097_SET_VIEWPORT_VERTICAL = 0x00000a04 >> 2, + NV4097_SET_POINT_CENTER_MODE = 0x00000a0c >> 2, + NV4097_ZCULL_SYNC = 0x00000a1c >> 2, + NV4097_SET_VIEWPORT_OFFSET = 0x00000a20 >> 2, + NV4097_SET_VIEWPORT_SCALE = 0x00000a30 >> 2, + NV4097_SET_POLY_OFFSET_POINT_ENABLE = 0x00000a60 >> 2, + NV4097_SET_POLY_OFFSET_LINE_ENABLE = 0x00000a64 >> 2, + NV4097_SET_POLY_OFFSET_FILL_ENABLE = 0x00000a68 >> 2, + NV4097_SET_DEPTH_FUNC = 0x00000a6c >> 2, + NV4097_SET_DEPTH_MASK = 0x00000a70 >> 2, + NV4097_SET_DEPTH_TEST_ENABLE = 0x00000a74 >> 2, + NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR = 0x00000a78 >> 2, + NV4097_SET_POLYGON_OFFSET_BIAS = 0x00000a7c >> 2, + NV4097_SET_VERTEX_DATA_SCALED4S_M = 0x00000a80 >> 2, + NV4097_SET_TEXTURE_CONTROL2 = 0x00000b00 >> 2, + NV4097_SET_TEX_COORD_CONTROL = 0x00000b40 >> 2, + NV4097_SET_TRANSFORM_PROGRAM = 0x00000b80 >> 2, + NV4097_SET_SPECULAR_ENABLE = 0x00001428 >> 2, + NV4097_SET_TWO_SIDE_LIGHT_EN = 0x0000142c >> 2, + NV4097_CLEAR_ZCULL_SURFACE = 0x00001438 >> 2, + NV4097_SET_PERFORMANCE_PARAMS = 0x00001450 >> 2, + NV4097_SET_FLAT_SHADE_OP = 0x00001454 >> 2, + NV4097_SET_EDGE_FLAG = 0x0000145c >> 2, + NV4097_SET_USER_CLIP_PLANE_CONTROL = 0x00001478 >> 2, + NV4097_SET_POLYGON_STIPPLE = 0x0000147c >> 2, + NV4097_SET_POLYGON_STIPPLE_PATTERN = 0x00001480 >> 2, + NV4097_SET_VERTEX_DATA3F_M = 0x00001500 >> 2, + NV4097_SET_VERTEX_DATA_ARRAY_OFFSET = 0x00001680 >> 2, + NV4097_INVALIDATE_VERTEX_CACHE_FILE = 0x00001710 >> 2, + NV4097_INVALIDATE_VERTEX_FILE = 0x00001714 >> 2, + NV4097_PIPE_NOP = 0x00001718 >> 2, + NV4097_SET_VERTEX_DATA_BASE_OFFSET = 0x00001738 >> 2, + NV4097_SET_VERTEX_DATA_BASE_INDEX = 0x0000173c >> 2, + NV4097_SET_VERTEX_DATA_ARRAY_FORMAT = 0x00001740 >> 2, + NV4097_CLEAR_REPORT_VALUE = 0x000017c8 >> 2, + NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE = 0x000017cc >> 2, + NV4097_GET_REPORT = 0x00001800 >> 2, + NV4097_SET_ZCULL_STATS_ENABLE = 0x00001804 >> 2, + NV4097_SET_BEGIN_END = 0x00001808 >> 2, + NV4097_ARRAY_ELEMENT16 = 0x0000180c >> 2, + NV4097_ARRAY_ELEMENT32 = 0x00001810 >> 2, + NV4097_DRAW_ARRAYS = 0x00001814 >> 2, + NV4097_INLINE_ARRAY = 0x00001818 >> 2, + NV4097_SET_INDEX_ARRAY_ADDRESS = 0x0000181c >> 2, + NV4097_SET_INDEX_ARRAY_DMA = 0x00001820 >> 2, + NV4097_DRAW_INDEX_ARRAY = 0x00001824 >> 2, + NV4097_SET_FRONT_POLYGON_MODE = 0x00001828 >> 2, + NV4097_SET_BACK_POLYGON_MODE = 0x0000182c >> 2, + NV4097_SET_CULL_FACE = 0x00001830 >> 2, + NV4097_SET_FRONT_FACE = 0x00001834 >> 2, + NV4097_SET_POLY_SMOOTH_ENABLE = 0x00001838 >> 2, + NV4097_SET_CULL_FACE_ENABLE = 0x0000183c >> 2, + NV4097_SET_TEXTURE_CONTROL3 = 0x00001840 >> 2, + NV4097_SET_VERTEX_DATA2F_M = 0x00001880 >> 2, + NV4097_SET_VERTEX_DATA2S_M = 0x00001900 >> 2, + NV4097_SET_VERTEX_DATA4UB_M = 0x00001940 >> 2, + NV4097_SET_VERTEX_DATA4S_M = 0x00001980 >> 2, + NV4097_SET_TEXTURE_OFFSET = 0x00001a00 >> 2, + NV4097_SET_TEXTURE_FORMAT = 0x00001a04 >> 2, + NV4097_SET_TEXTURE_ADDRESS = 0x00001a08 >> 2, + NV4097_SET_TEXTURE_CONTROL0 = 0x00001a0c >> 2, + NV4097_SET_TEXTURE_CONTROL1 = 0x00001a10 >> 2, + NV4097_SET_TEXTURE_FILTER = 0x00001a14 >> 2, + NV4097_SET_TEXTURE_IMAGE_RECT = 0x00001a18 >> 2, + NV4097_SET_TEXTURE_BORDER_COLOR = 0x00001a1c >> 2, + NV4097_SET_VERTEX_DATA4F_M = 0x00001c00 >> 2, + NV4097_SET_COLOR_KEY_COLOR = 0x00001d00 >> 2, + NV4097_SET_SHADER_CONTROL = 0x00001d60 >> 2, + NV4097_SET_INDEXED_CONSTANT_READ_LIMITS = 0x00001d64 >> 2, + NV4097_SET_SEMAPHORE_OFFSET = 0x00001d6c >> 2, + NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE = 0x00001d70 >> 2, + NV4097_TEXTURE_READ_SEMAPHORE_RELEASE = 0x00001d74 >> 2, + NV4097_SET_ZMIN_MAX_CONTROL = 0x00001d78 >> 2, + NV4097_SET_ANTI_ALIASING_CONTROL = 0x00001d7c >> 2, + NV4097_SET_SURFACE_COMPRESSION = 0x00001d80 >> 2, + NV4097_SET_ZCULL_EN = 0x00001d84 >> 2, + NV4097_SET_SHADER_WINDOW = 0x00001d88 >> 2, + NV4097_SET_ZSTENCIL_CLEAR_VALUE = 0x00001d8c >> 2, + NV4097_SET_COLOR_CLEAR_VALUE = 0x00001d90 >> 2, + NV4097_CLEAR_SURFACE = 0x00001d94 >> 2, + NV4097_SET_CLEAR_RECT_HORIZONTAL = 0x00001d98 >> 2, + NV4097_SET_CLEAR_RECT_VERTICAL = 0x00001d9c >> 2, + NV4097_SET_CLIP_ID_TEST_ENABLE = 0x00001da4 >> 2, + NV4097_SET_RESTART_INDEX_ENABLE = 0x00001dac >> 2, + NV4097_SET_RESTART_INDEX = 0x00001db0 >> 2, + NV4097_SET_LINE_STIPPLE = 0x00001db4 >> 2, + NV4097_SET_LINE_STIPPLE_PATTERN = 0x00001db8 >> 2, + NV4097_SET_VERTEX_DATA1F_M = 0x00001e40 >> 2, + NV4097_SET_TRANSFORM_EXECUTION_MODE = 0x00001e94 >> 2, + NV4097_SET_RENDER_ENABLE = 0x00001e98 >> 2, + NV4097_SET_TRANSFORM_PROGRAM_LOAD = 0x00001e9c >> 2, + NV4097_SET_TRANSFORM_PROGRAM_START = 0x00001ea0 >> 2, + NV4097_SET_ZCULL_CONTROL0 = 0x00001ea4 >> 2, + NV4097_SET_ZCULL_CONTROL1 = 0x00001ea8 >> 2, + NV4097_SET_SCULL_CONTROL = 0x00001eac >> 2, + NV4097_SET_POINT_SIZE = 0x00001ee0 >> 2, + NV4097_SET_POINT_PARAMS_ENABLE = 0x00001ee4 >> 2, + NV4097_SET_POINT_SPRITE_CONTROL = 0x00001ee8 >> 2, + NV4097_SET_TRANSFORM_TIMEOUT = 0x00001ef8 >> 2, + NV4097_SET_TRANSFORM_CONSTANT_LOAD = 0x00001efc >> 2, + NV4097_SET_TRANSFORM_CONSTANT = 0x00001f00 >> 2, + NV4097_SET_FREQUENCY_DIVIDER_OPERATION = 0x00001fc0 >> 2, + NV4097_SET_ATTRIB_COLOR = 0x00001fc4 >> 2, + NV4097_SET_ATTRIB_TEX_COORD = 0x00001fc8 >> 2, + NV4097_SET_ATTRIB_TEX_COORD_EX = 0x00001fcc >> 2, + NV4097_SET_ATTRIB_UCLIP0 = 0x00001fd0 >> 2, + NV4097_SET_ATTRIB_UCLIP1 = 0x00001fd4 >> 2, + NV4097_INVALIDATE_L2 = 0x00001fd8 >> 2, + NV4097_SET_REDUCE_DST_COLOR = 0x00001fe0 >> 2, + NV4097_SET_NO_PARANOID_TEXTURE_FETCHES = 0x00001fe8 >> 2, + NV4097_SET_SHADER_PACKER = 0x00001fec >> 2, + NV4097_SET_VERTEX_ATTRIB_INPUT_MASK = 0x00001ff0 >> 2, + NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK = 0x00001ff4 >> 2, + NV4097_SET_TRANSFORM_BRANCH_BITS = 0x00001ff8 >> 2, // NV03_MEMORY_TO_MEMORY_FORMAT (NV0039) - NV0039_SET_OBJECT = 0x00002000, - NV0039_SET_CONTEXT_DMA_NOTIFIES = 0x00002180, - NV0039_SET_CONTEXT_DMA_BUFFER_IN = 0x00002184, - NV0039_SET_CONTEXT_DMA_BUFFER_OUT = 0x00002188, - NV0039_OFFSET_IN = 0x0000230C, - NV0039_OFFSET_OUT = 0x00002310, - NV0039_PITCH_IN = 0x00002314, - NV0039_PITCH_OUT = 0x00002318, - NV0039_LINE_LENGTH_IN = 0x0000231C, - NV0039_LINE_COUNT = 0x00002320, - NV0039_FORMAT = 0x00002324, - NV0039_BUFFER_NOTIFY = 0x00002328, + NV0039_SET_OBJECT = 0x00002000 >> 2, + NV0039_SET_CONTEXT_DMA_NOTIFIES = 0x00002180 >> 2, + NV0039_SET_CONTEXT_DMA_BUFFER_IN = 0x00002184 >> 2, + NV0039_SET_CONTEXT_DMA_BUFFER_OUT = 0x00002188 >> 2, + NV0039_OFFSET_IN = 0x0000230C >> 2, + NV0039_OFFSET_OUT = 0x00002310 >> 2, + NV0039_PITCH_IN = 0x00002314 >> 2, + NV0039_PITCH_OUT = 0x00002318 >> 2, + NV0039_LINE_LENGTH_IN = 0x0000231C >> 2, + NV0039_LINE_COUNT = 0x00002320 >> 2, + NV0039_FORMAT = 0x00002324 >> 2, + NV0039_BUFFER_NOTIFY = 0x00002328 >> 2, // NV30_CONTEXT_SURFACES_2D (NV3062) - NV3062_SET_OBJECT = 0x00006000, - NV3062_SET_CONTEXT_DMA_NOTIFIES = 0x00006180, - NV3062_SET_CONTEXT_DMA_IMAGE_SOURCE = 0x00006184, - NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN = 0x00006188, - NV3062_SET_COLOR_FORMAT = 0x00006300, - NV3062_SET_PITCH = 0x00006304, - NV3062_SET_OFFSET_SOURCE = 0x00006308, - NV3062_SET_OFFSET_DESTIN = 0x0000630C, + NV3062_SET_OBJECT = 0x00006000 >> 2, + NV3062_SET_CONTEXT_DMA_NOTIFIES = 0x00006180 >> 2, + NV3062_SET_CONTEXT_DMA_IMAGE_SOURCE = 0x00006184 >> 2, + NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN = 0x00006188 >> 2, + NV3062_SET_COLOR_FORMAT = 0x00006300 >> 2, + NV3062_SET_PITCH = 0x00006304 >> 2, + NV3062_SET_OFFSET_SOURCE = 0x00006308 >> 2, + NV3062_SET_OFFSET_DESTIN = 0x0000630C >> 2, // NV30_CONTEXT_SURFACE_SWIZZLED (NV309E) - NV309E_SET_OBJECT = 0x00008000, - NV309E_SET_CONTEXT_DMA_NOTIFIES = 0x00008180, - NV309E_SET_CONTEXT_DMA_IMAGE = 0x00008184, - NV309E_SET_FORMAT = 0x00008300, - NV309E_SET_OFFSET = 0x00008304, + NV309E_SET_OBJECT = 0x00008000 >> 2, + NV309E_SET_CONTEXT_DMA_NOTIFIES = 0x00008180 >> 2, + NV309E_SET_CONTEXT_DMA_IMAGE = 0x00008184 >> 2, + NV309E_SET_FORMAT = 0x00008300 >> 2, + NV309E_SET_OFFSET = 0x00008304 >> 2, // NV30_IMAGE_FROM_CPU (NV308A) - NV308A_SET_OBJECT = 0x0000A000, - NV308A_SET_CONTEXT_DMA_NOTIFIES = 0x0000A180, - NV308A_SET_CONTEXT_COLOR_KEY = 0x0000A184, - NV308A_SET_CONTEXT_CLIP_RECTANGLE = 0x0000A188, - NV308A_SET_CONTEXT_PATTERN = 0x0000A18C, - NV308A_SET_CONTEXT_ROP = 0x0000A190, - NV308A_SET_CONTEXT_BETA1 = 0x0000A194, - NV308A_SET_CONTEXT_BETA4 = 0x0000A198, - NV308A_SET_CONTEXT_SURFACE = 0x0000A19C, - NV308A_SET_COLOR_CONVERSION = 0x0000A2F8, - NV308A_SET_OPERATION = 0x0000A2FC, - NV308A_SET_COLOR_FORMAT = 0x0000A300, - NV308A_POINT = 0x0000A304, - NV308A_SIZE_OUT = 0x0000A308, - NV308A_SIZE_IN = 0x0000A30C, - NV308A_COLOR = 0x0000A400, + NV308A_SET_OBJECT = 0x0000A000 >> 2, + NV308A_SET_CONTEXT_DMA_NOTIFIES = 0x0000A180 >> 2, + NV308A_SET_CONTEXT_COLOR_KEY = 0x0000A184 >> 2, + NV308A_SET_CONTEXT_CLIP_RECTANGLE = 0x0000A188 >> 2, + NV308A_SET_CONTEXT_PATTERN = 0x0000A18C >> 2, + NV308A_SET_CONTEXT_ROP = 0x0000A190 >> 2, + NV308A_SET_CONTEXT_BETA1 = 0x0000A194 >> 2, + NV308A_SET_CONTEXT_BETA4 = 0x0000A198 >> 2, + NV308A_SET_CONTEXT_SURFACE = 0x0000A19C >> 2, + NV308A_SET_COLOR_CONVERSION = 0x0000A2F8 >> 2, + NV308A_SET_OPERATION = 0x0000A2FC >> 2, + NV308A_SET_COLOR_FORMAT = 0x0000A300 >> 2, + NV308A_POINT = 0x0000A304 >> 2, + NV308A_SIZE_OUT = 0x0000A308 >> 2, + NV308A_SIZE_IN = 0x0000A30C >> 2, + NV308A_COLOR = 0x0000A400 >> 2, // NV30_SCALED_IMAGE_FROM_MEMORY (NV3089) - NV3089_SET_OBJECT = 0x0000C000, - NV3089_SET_CONTEXT_DMA_NOTIFIES = 0x0000C180, - NV3089_SET_CONTEXT_DMA_IMAGE = 0x0000C184, - NV3089_SET_CONTEXT_PATTERN = 0x0000C188, - NV3089_SET_CONTEXT_ROP = 0x0000C18C, - NV3089_SET_CONTEXT_BETA1 = 0x0000C190, - NV3089_SET_CONTEXT_BETA4 = 0x0000C194, - NV3089_SET_CONTEXT_SURFACE = 0x0000C198, - NV3089_SET_COLOR_CONVERSION = 0x0000C2FC, - NV3089_SET_COLOR_FORMAT = 0x0000C300, - NV3089_SET_OPERATION = 0x0000C304, - NV3089_CLIP_POINT = 0x0000C308, - NV3089_CLIP_SIZE = 0x0000C30C, - NV3089_IMAGE_OUT_POINT = 0x0000C310, - NV3089_IMAGE_OUT_SIZE = 0x0000C314, - NV3089_DS_DX = 0x0000C318, - NV3089_DT_DY = 0x0000C31C, - NV3089_IMAGE_IN_SIZE = 0x0000C400, - NV3089_IMAGE_IN_FORMAT = 0x0000C404, - NV3089_IMAGE_IN_OFFSET = 0x0000C408, - NV3089_IMAGE_IN = 0x0000C40C, + NV3089_SET_OBJECT = 0x0000C000 >> 2, + NV3089_SET_CONTEXT_DMA_NOTIFIES = 0x0000C180 >> 2, + NV3089_SET_CONTEXT_DMA_IMAGE = 0x0000C184 >> 2, + NV3089_SET_CONTEXT_PATTERN = 0x0000C188 >> 2, + NV3089_SET_CONTEXT_ROP = 0x0000C18C >> 2, + NV3089_SET_CONTEXT_BETA1 = 0x0000C190 >> 2, + NV3089_SET_CONTEXT_BETA4 = 0x0000C194 >> 2, + NV3089_SET_CONTEXT_SURFACE = 0x0000C198 >> 2, + NV3089_SET_COLOR_CONVERSION = 0x0000C2FC >> 2, + NV3089_SET_COLOR_FORMAT = 0x0000C300 >> 2, + NV3089_SET_OPERATION = 0x0000C304 >> 2, + NV3089_CLIP_POINT = 0x0000C308 >> 2, + NV3089_CLIP_SIZE = 0x0000C30C >> 2, + NV3089_IMAGE_OUT_POINT = 0x0000C310 >> 2, + NV3089_IMAGE_OUT_SIZE = 0x0000C314 >> 2, + NV3089_DS_DX = 0x0000C318 >> 2, + NV3089_DT_DY = 0x0000C31C >> 2, + NV3089_IMAGE_IN_SIZE = 0x0000C400 >> 2, + NV3089_IMAGE_IN_FORMAT = 0x0000C404 >> 2, + NV3089_IMAGE_IN_OFFSET = 0x0000C408 >> 2, + NV3089_IMAGE_IN = 0x0000C40C >> 2, - GCM_SET_USER_COMMAND = 0x0000EB00, + GCM_SET_USER_COMMAND = 0x0000EB00 >> 2, + + GCM_FLIP_COMMAND = 0x0000FEAC >> 2 }; -static const std::string GetMethodName(const u32 id) -{ - struct MethodName - { - const u32 id; - const std::string& name; - } static const METHOD_NAME_LIST[] = { - { NV4097_NO_OPERATION , "NV4097_NO_OPERATION" }, - { NV4097_NOTIFY , "NV4097_NOTIFY" }, - { NV4097_WAIT_FOR_IDLE , "NV4097_WAIT_FOR_IDLE" }, - { NV4097_PM_TRIGGER , "NV4097_PM_TRIGGER" }, - { NV4097_SET_CONTEXT_DMA_NOTIFIES , "NV4097_SET_CONTEXT_DMA_NOTIFIES" }, - { NV4097_SET_CONTEXT_DMA_A , "NV4097_SET_CONTEXT_DMA_A" }, - { NV4097_SET_CONTEXT_DMA_B , "NV4097_SET_CONTEXT_DMA_B" }, - { NV4097_SET_CONTEXT_DMA_COLOR_B , "NV4097_SET_CONTEXT_DMA_COLOR_B" }, - { NV4097_SET_CONTEXT_DMA_STATE , "NV4097_SET_CONTEXT_DMA_STATE" }, - { NV4097_SET_CONTEXT_DMA_COLOR_A , "NV4097_SET_CONTEXT_DMA_COLOR_A" }, - { NV4097_SET_CONTEXT_DMA_ZETA , "NV4097_SET_CONTEXT_DMA_ZETA" }, - { NV4097_SET_CONTEXT_DMA_VERTEX_A , "NV4097_SET_CONTEXT_DMA_VERTEX_A" }, - { NV4097_SET_CONTEXT_DMA_VERTEX_B , "NV4097_SET_CONTEXT_DMA_VERTEX_B" }, - { NV4097_SET_CONTEXT_DMA_SEMAPHORE , "NV4097_SET_CONTEXT_DMA_SEMAPHORE" }, - { NV4097_SET_CONTEXT_DMA_REPORT , "NV4097_SET_CONTEXT_DMA_REPORT" }, - { NV4097_SET_CONTEXT_DMA_CLIP_ID , "NV4097_SET_CONTEXT_DMA_CLIP_ID" }, - { NV4097_SET_CONTEXT_DMA_CULL_DATA , "NV4097_SET_CONTEXT_DMA_CULL_DATA" }, - { NV4097_SET_CONTEXT_DMA_COLOR_C , "NV4097_SET_CONTEXT_DMA_COLOR_C" }, - { NV4097_SET_CONTEXT_DMA_COLOR_D , "NV4097_SET_CONTEXT_DMA_COLOR_D" }, - { NV4097_SET_SURFACE_CLIP_HORIZONTAL , "NV4097_SET_SURFACE_CLIP_HORIZONTAL" }, - { NV4097_SET_SURFACE_CLIP_VERTICAL , "NV4097_SET_SURFACE_CLIP_VERTICAL" }, - { NV4097_SET_SURFACE_FORMAT , "NV4097_SET_SURFACE_FORMAT" }, - { NV4097_SET_SURFACE_PITCH_A , "NV4097_SET_SURFACE_PITCH_A" }, - { NV4097_SET_SURFACE_COLOR_AOFFSET , "NV4097_SET_SURFACE_COLOR_AOFFSET" }, - { NV4097_SET_SURFACE_ZETA_OFFSET , "NV4097_SET_SURFACE_ZETA_OFFSET" }, - { NV4097_SET_SURFACE_COLOR_BOFFSET , "NV4097_SET_SURFACE_COLOR_BOFFSET" }, - { NV4097_SET_SURFACE_PITCH_B , "NV4097_SET_SURFACE_PITCH_B" }, - { NV4097_SET_SURFACE_COLOR_TARGET , "NV4097_SET_SURFACE_COLOR_TARGET" }, - { NV4097_SET_SURFACE_PITCH_Z , "NV4097_SET_SURFACE_PITCH_Z" }, - { NV4097_INVALIDATE_ZCULL , "NV4097_INVALIDATE_ZCULL" }, - { NV4097_SET_CYLINDRICAL_WRAP , "NV4097_SET_CYLINDRICAL_WRAP" }, - { NV4097_SET_CYLINDRICAL_WRAP1 , "NV4097_SET_CYLINDRICAL_WRAP1" }, - { NV4097_SET_SURFACE_PITCH_C , "NV4097_SET_SURFACE_PITCH_C" }, - { NV4097_SET_SURFACE_PITCH_D , "NV4097_SET_SURFACE_PITCH_D" }, - { NV4097_SET_SURFACE_COLOR_COFFSET , "NV4097_SET_SURFACE_COLOR_COFFSET" }, - { NV4097_SET_SURFACE_COLOR_DOFFSET , "NV4097_SET_SURFACE_COLOR_DOFFSET" }, - { NV4097_SET_WINDOW_OFFSET , "NV4097_SET_WINDOW_OFFSET" }, - { NV4097_SET_DITHER_ENABLE , "NV4097_SET_DITHER_ENABLE" }, - { NV4097_SET_ALPHA_TEST_ENABLE , "NV4097_SET_ALPHA_TEST_ENABLE" }, - { NV4097_SET_ALPHA_FUNC , "NV4097_SET_ALPHA_FUNC" }, - { NV4097_SET_ALPHA_REF , "NV4097_SET_ALPHA_REF" }, - { NV4097_SET_BLEND_ENABLE , "NV4097_SET_BLEND_ENABLE" }, - { NV4097_SET_BLEND_FUNC_SFACTOR , "NV4097_SET_BLEND_FUNC_SFACTOR" }, - { NV4097_SET_BLEND_FUNC_DFACTOR , "NV4097_SET_BLEND_FUNC_DFACTOR" }, - { NV4097_SET_BLEND_COLOR , "NV4097_SET_BLEND_COLOR" }, - { NV4097_SET_BLEND_EQUATION , "NV4097_SET_BLEND_EQUATION" }, - { NV4097_SET_COLOR_MASK , "NV4097_SET_COLOR_MASK" }, - { NV4097_SET_STENCIL_TEST_ENABLE , "NV4097_SET_STENCIL_TEST_ENABLE" }, - { NV4097_SET_STENCIL_MASK , "NV4097_SET_STENCIL_MASK" }, - { NV4097_SET_STENCIL_FUNC , "NV4097_SET_STENCIL_FUNC" }, - { NV4097_SET_STENCIL_FUNC_REF , "NV4097_SET_STENCIL_FUNC_REF" }, - { NV4097_SET_STENCIL_FUNC_MASK , "NV4097_SET_STENCIL_FUNC_MASK" }, - { NV4097_SET_STENCIL_OP_FAIL , "NV4097_SET_STENCIL_OP_FAIL" }, - { NV4097_SET_STENCIL_OP_ZFAIL , "NV4097_SET_STENCIL_OP_ZFAIL" }, - { NV4097_SET_STENCIL_OP_ZPASS , "NV4097_SET_STENCIL_OP_ZPASS" }, - { NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE , "NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE" }, - { NV4097_SET_BACK_STENCIL_MASK , "NV4097_SET_BACK_STENCIL_MASK" }, - { NV4097_SET_BACK_STENCIL_FUNC , "NV4097_SET_BACK_STENCIL_FUNC" }, - { NV4097_SET_BACK_STENCIL_FUNC_REF , "NV4097_SET_BACK_STENCIL_FUNC_REF" }, - { NV4097_SET_BACK_STENCIL_FUNC_MASK , "NV4097_SET_BACK_STENCIL_FUNC_MASK" }, - { NV4097_SET_BACK_STENCIL_OP_FAIL , "NV4097_SET_BACK_STENCIL_OP_FAIL" }, - { NV4097_SET_BACK_STENCIL_OP_ZFAIL , "NV4097_SET_BACK_STENCIL_OP_ZFAIL" }, - { NV4097_SET_BACK_STENCIL_OP_ZPASS , "NV4097_SET_BACK_STENCIL_OP_ZPASS" }, - { NV4097_SET_SHADE_MODE , "NV4097_SET_SHADE_MODE" }, - { NV4097_SET_BLEND_ENABLE_MRT , "NV4097_SET_BLEND_ENABLE_MRT" }, - { NV4097_SET_COLOR_MASK_MRT , "NV4097_SET_COLOR_MASK_MRT" }, - { NV4097_SET_LOGIC_OP_ENABLE , "NV4097_SET_LOGIC_OP_ENABLE" }, - { NV4097_SET_LOGIC_OP , "NV4097_SET_LOGIC_OP" }, - { NV4097_SET_BLEND_COLOR2 , "NV4097_SET_BLEND_COLOR2" }, - { NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE , "NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE" }, - { NV4097_SET_DEPTH_BOUNDS_MIN , "NV4097_SET_DEPTH_BOUNDS_MIN" }, - { NV4097_SET_DEPTH_BOUNDS_MAX , "NV4097_SET_DEPTH_BOUNDS_MAX" }, - { NV4097_SET_CLIP_MIN , "NV4097_SET_CLIP_MIN" }, - { NV4097_SET_CLIP_MAX , "NV4097_SET_CLIP_MAX" }, - { NV4097_SET_CONTROL0 , "NV4097_SET_CONTROL0" }, - { NV4097_SET_LINE_WIDTH , "NV4097_SET_LINE_WIDTH" }, - { NV4097_SET_LINE_SMOOTH_ENABLE , "NV4097_SET_LINE_SMOOTH_ENABLE" }, - { NV4097_SET_ANISO_SPREAD , "NV4097_SET_ANISO_SPREAD" }, - { NV4097_SET_ANISO_SPREAD + 4 , "NV4097_SET_ANISO_SPREAD + 4" }, - { NV4097_SET_ANISO_SPREAD + 8 , "NV4097_SET_ANISO_SPREAD + 8" }, - { NV4097_SET_ANISO_SPREAD + 12 , "NV4097_SET_ANISO_SPREAD + 12" }, - { NV4097_SET_ANISO_SPREAD + 16 , "NV4097_SET_ANISO_SPREAD + 16" }, - { NV4097_SET_ANISO_SPREAD + 20 , "NV4097_SET_ANISO_SPREAD + 20" }, - { NV4097_SET_ANISO_SPREAD + 24 , "NV4097_SET_ANISO_SPREAD + 24" }, - { NV4097_SET_ANISO_SPREAD + 28 , "NV4097_SET_ANISO_SPREAD + 28" }, - { NV4097_SET_ANISO_SPREAD + 32 , "NV4097_SET_ANISO_SPREAD + 32" }, - { NV4097_SET_ANISO_SPREAD + 36 , "NV4097_SET_ANISO_SPREAD + 36" }, - { NV4097_SET_ANISO_SPREAD + 40 , "NV4097_SET_ANISO_SPREAD + 40" }, - { NV4097_SET_ANISO_SPREAD + 44 , "NV4097_SET_ANISO_SPREAD + 44" }, - { NV4097_SET_ANISO_SPREAD + 48 , "NV4097_SET_ANISO_SPREAD + 48" }, - { NV4097_SET_ANISO_SPREAD + 52 , "NV4097_SET_ANISO_SPREAD + 52" }, - { NV4097_SET_ANISO_SPREAD + 56 , "NV4097_SET_ANISO_SPREAD + 56" }, - { NV4097_SET_ANISO_SPREAD + 60 , "NV4097_SET_ANISO_SPREAD + 60" }, - { NV4097_SET_SCISSOR_HORIZONTAL , "NV4097_SET_SCISSOR_HORIZONTAL" }, - { NV4097_SET_SCISSOR_VERTICAL , "NV4097_SET_SCISSOR_VERTICAL" }, - { NV4097_SET_FOG_MODE , "NV4097_SET_FOG_MODE" }, - { NV4097_SET_FOG_PARAMS , "NV4097_SET_FOG_PARAMS" }, - { NV4097_SET_FOG_PARAMS + 4 , "NV4097_SET_FOG_PARAMS + 4" }, - { NV4097_SET_FOG_PARAMS + 8 , "NV4097_SET_FOG_PARAMS + 8" }, - { NV4097_SET_SHADER_PROGRAM , "NV4097_SET_SHADER_PROGRAM" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET , "NV4097_SET_VERTEX_TEXTURE_OFFSET" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT , "NV4097_SET_VERTEX_TEXTURE_FORMAT" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS , "NV4097_SET_VERTEX_TEXTURE_ADDRESS" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 , "NV4097_SET_VERTEX_TEXTURE_CONTROL0" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 , "NV4097_SET_VERTEX_TEXTURE_CONTROL3" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER , "NV4097_SET_VERTEX_TEXTURE_FILTER" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT , "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR , "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40" }, - { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60" }, - { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60" }, - { NV4097_SET_VIEWPORT_HORIZONTAL , "NV4097_SET_VIEWPORT_HORIZONTAL" }, - { NV4097_SET_VIEWPORT_VERTICAL , "NV4097_SET_VIEWPORT_VERTICAL" }, - { NV4097_SET_VIEWPORT_OFFSET , "NV4097_SET_VIEWPORT_OFFSET" }, - { NV4097_SET_VIEWPORT_SCALE , "NV4097_SET_VIEWPORT_SCALE" }, - { NV4097_SET_POLY_OFFSET_LINE_ENABLE , "NV4097_SET_POLY_OFFSET_LINE_ENABLE" }, - { NV4097_SET_POLY_OFFSET_FILL_ENABLE , "NV4097_SET_POLY_OFFSET_FILL_ENABLE" }, - { NV4097_SET_DEPTH_FUNC , "NV4097_SET_DEPTH_FUNC" }, - { NV4097_SET_DEPTH_MASK , "NV4097_SET_DEPTH_MASK" }, - { NV4097_SET_DEPTH_TEST_ENABLE , "NV4097_SET_DEPTH_TEST_ENABLE" }, - { NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR , "NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR" }, - { NV4097_SET_POLYGON_OFFSET_BIAS , "NV4097_SET_POLYGON_OFFSET_BIAS" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M , "NV4097_SET_VERTEX_DATA_SCALED4S_M" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 4 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 4" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 8 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 8" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 12 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 12" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 16 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 16" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 20 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 20" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 24 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 24" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 28 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 28" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 32 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 32" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 36 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 36" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 40, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 40" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 44 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 44" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 48 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 48" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 52 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 52" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 56 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 56" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 60 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 60" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 64 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 64" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 68 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 68" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 72 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 72" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 76 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 76" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 80 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 80" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 84 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 84" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 88 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 88" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 92 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 92" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 96 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 96" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 100 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 100" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 104 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 104" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 108 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 108" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 112 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 112" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 116 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 116" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 120 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 120" }, - { NV4097_SET_VERTEX_DATA_SCALED4S_M + 124 , "NV4097_SET_VERTEX_DATA_SCALED4S_M + 124" }, - { NV4097_SET_TEXTURE_CONTROL2 , "NV4097_SET_TEXTURE_CONTROL2" }, - { NV4097_SET_TEXTURE_CONTROL2 + 4 , "NV4097_SET_TEXTURE_CONTROL2 + 4" }, - { NV4097_SET_TEXTURE_CONTROL2 + 8 , "NV4097_SET_TEXTURE_CONTROL2 + 8" }, - { NV4097_SET_TEXTURE_CONTROL2 + 12 , "NV4097_SET_TEXTURE_CONTROL2 + 12" }, - { NV4097_SET_TEXTURE_CONTROL2 + 16 , "NV4097_SET_TEXTURE_CONTROL2 + 16" }, - { NV4097_SET_TEXTURE_CONTROL2 + 20 , "NV4097_SET_TEXTURE_CONTROL2 + 20" }, - { NV4097_SET_TEXTURE_CONTROL2 + 24 , "NV4097_SET_TEXTURE_CONTROL2 + 24" }, - { NV4097_SET_TEXTURE_CONTROL2 + 28 , "NV4097_SET_TEXTURE_CONTROL2 + 28" }, - { NV4097_SET_TEXTURE_CONTROL2 + 32 , "NV4097_SET_TEXTURE_CONTROL2 + 32" }, - { NV4097_SET_TEXTURE_CONTROL2 + 36 , "NV4097_SET_TEXTURE_CONTROL2 + 36" }, - { NV4097_SET_TEXTURE_CONTROL2 + 40 , "NV4097_SET_TEXTURE_CONTROL2 + 40" }, - { NV4097_SET_TEXTURE_CONTROL2 + 44 , "NV4097_SET_TEXTURE_CONTROL2 + 44" }, - { NV4097_SET_TEXTURE_CONTROL2 + 48 , "NV4097_SET_TEXTURE_CONTROL2 + 48" }, - { NV4097_SET_TEXTURE_CONTROL2 + 52 , "NV4097_SET_TEXTURE_CONTROL2 + 52" }, - { NV4097_SET_TEXTURE_CONTROL2 + 56 , "NV4097_SET_TEXTURE_CONTROL2 + 56" }, - { NV4097_SET_TEXTURE_CONTROL2 + 60 , "NV4097_SET_TEXTURE_CONTROL2 + 60" }, - { NV4097_SET_TEX_COORD_CONTROL , "NV4097_SET_TEX_COORD_CONTROL" }, - { NV4097_SET_TEX_COORD_CONTROL + 4 , "NV4097_SET_TEX_COORD_CONTROL + 4" }, - { NV4097_SET_TEX_COORD_CONTROL + 8 , "NV4097_SET_TEX_COORD_CONTROL + 8" }, - { NV4097_SET_TEX_COORD_CONTROL + 12 , "NV4097_SET_TEX_COORD_CONTROL + 12" }, - { NV4097_SET_TEX_COORD_CONTROL + 16 , "NV4097_SET_TEX_COORD_CONTROL + 16" }, - { NV4097_SET_TEX_COORD_CONTROL + 20 , "NV4097_SET_TEX_COORD_CONTROL + 20" }, - { NV4097_SET_TEX_COORD_CONTROL + 24 , "NV4097_SET_TEX_COORD_CONTROL + 24" }, - { NV4097_SET_TEX_COORD_CONTROL + 28 , "NV4097_SET_TEX_COORD_CONTROL + 28" }, - { NV4097_SET_TEX_COORD_CONTROL + 32 , "NV4097_SET_TEX_COORD_CONTROL + 32" }, - { NV4097_SET_TEX_COORD_CONTROL + 36 , "NV4097_SET_TEX_COORD_CONTROL + 36" }, - { NV4097_SET_TRANSFORM_PROGRAM , "NV4097_SET_TRANSFORM_PROGRAM" }, - { NV4097_SET_TRANSFORM_PROGRAM + 4 , "NV4097_SET_TRANSFORM_PROGRAM + 4" }, - { NV4097_SET_TRANSFORM_PROGRAM + 8 , "NV4097_SET_TRANSFORM_PROGRAM + 8" }, - { NV4097_SET_TRANSFORM_PROGRAM + 12 , "NV4097_SET_TRANSFORM_PROGRAM + 12" }, - { NV4097_SET_TRANSFORM_PROGRAM + 16 , "NV4097_SET_TRANSFORM_PROGRAM + 16" }, - { NV4097_SET_TRANSFORM_PROGRAM + 20 , "NV4097_SET_TRANSFORM_PROGRAM + 20" }, - { NV4097_SET_TRANSFORM_PROGRAM + 24 , "NV4097_SET_TRANSFORM_PROGRAM + 24" }, - { NV4097_SET_TRANSFORM_PROGRAM + 28 , "NV4097_SET_TRANSFORM_PROGRAM + 28" }, - { NV4097_SET_TRANSFORM_PROGRAM + 32 , "NV4097_SET_TRANSFORM_PROGRAM + 32" }, - { NV4097_SET_TRANSFORM_PROGRAM + 36 , "NV4097_SET_TRANSFORM_PROGRAM + 36" }, - { NV4097_SET_TRANSFORM_PROGRAM + 40 , "NV4097_SET_TRANSFORM_PROGRAM + 40" }, - { NV4097_SET_TRANSFORM_PROGRAM + 44 , "NV4097_SET_TRANSFORM_PROGRAM + 44" }, - { NV4097_SET_TRANSFORM_PROGRAM + 48 , "NV4097_SET_TRANSFORM_PROGRAM + 48" }, - { NV4097_SET_TRANSFORM_PROGRAM + 52 , "NV4097_SET_TRANSFORM_PROGRAM + 52" }, - { NV4097_SET_TRANSFORM_PROGRAM + 56 , "NV4097_SET_TRANSFORM_PROGRAM + 56" }, - { NV4097_SET_TRANSFORM_PROGRAM + 60 , "NV4097_SET_TRANSFORM_PROGRAM + 60" }, - { NV4097_SET_TRANSFORM_PROGRAM + 64 , "NV4097_SET_TRANSFORM_PROGRAM + 64" }, - { NV4097_SET_TRANSFORM_PROGRAM + 68 , "NV4097_SET_TRANSFORM_PROGRAM + 68" }, - { NV4097_SET_TRANSFORM_PROGRAM + 72 , "NV4097_SET_TRANSFORM_PROGRAM + 72" }, - { NV4097_SET_TRANSFORM_PROGRAM + 76 , "NV4097_SET_TRANSFORM_PROGRAM + 76" }, - { NV4097_SET_TRANSFORM_PROGRAM + 80 , "NV4097_SET_TRANSFORM_PROGRAM + 80" }, - { NV4097_SET_TRANSFORM_PROGRAM + 84 , "NV4097_SET_TRANSFORM_PROGRAM + 84" }, - { NV4097_SET_TRANSFORM_PROGRAM + 88 , "NV4097_SET_TRANSFORM_PROGRAM + 88" }, - { NV4097_SET_TRANSFORM_PROGRAM + 92 , "NV4097_SET_TRANSFORM_PROGRAM + 92" }, - { NV4097_SET_TRANSFORM_PROGRAM + 96 , "NV4097_SET_TRANSFORM_PROGRAM + 96" }, - { NV4097_SET_TRANSFORM_PROGRAM + 100 , "NV4097_SET_TRANSFORM_PROGRAM + 100" }, - { NV4097_SET_TRANSFORM_PROGRAM + 104 , "NV4097_SET_TRANSFORM_PROGRAM + 104" }, - { NV4097_SET_TRANSFORM_PROGRAM + 108 , "NV4097_SET_TRANSFORM_PROGRAM + 108" }, - { NV4097_SET_TRANSFORM_PROGRAM + 112 , "NV4097_SET_TRANSFORM_PROGRAM + 112" }, - { NV4097_SET_TRANSFORM_PROGRAM + 116 , "NV4097_SET_TRANSFORM_PROGRAM + 116" }, - { NV4097_SET_TRANSFORM_PROGRAM + 120 , "NV4097_SET_TRANSFORM_PROGRAM + 120" }, - { NV4097_SET_TRANSFORM_PROGRAM + 124 , "NV4097_SET_TRANSFORM_PROGRAM + 124" }, - { NV4097_SET_TWO_SIDE_LIGHT_EN , "NV4097_SET_TWO_SIDE_LIGHT_EN" }, - { NV4097_CLEAR_ZCULL_SURFACE , "NV4097_CLEAR_ZCULL_SURFACE" }, - { NV4097_SET_USER_CLIP_PLANE_CONTROL , "NV4097_SET_USER_CLIP_PLANE_CONTROL" }, - { NV4097_SET_POLYGON_STIPPLE , "NV4097_SET_POLYGON_STIPPLE" }, - { NV4097_SET_POLYGON_STIPPLE_PATTERN , "NV4097_SET_POLYGON_STIPPLE_PATTERN" }, - { NV4097_SET_VERTEX_DATA3F_M , "NV4097_SET_VERTEX_DATA3F_M" }, - { NV4097_SET_VERTEX_DATA3F_M + 4 , "NV4097_SET_VERTEX_DATA3F_M + 4" }, - { NV4097_SET_VERTEX_DATA3F_M + 8 , "NV4097_SET_VERTEX_DATA3F_M + 8" }, - { NV4097_SET_VERTEX_DATA3F_M + 12 , "NV4097_SET_VERTEX_DATA3F_M + 12" }, - { NV4097_SET_VERTEX_DATA3F_M + 16 , "NV4097_SET_VERTEX_DATA3F_M + 16" }, - { NV4097_SET_VERTEX_DATA3F_M + 20 , "NV4097_SET_VERTEX_DATA3F_M + 20" }, - { NV4097_SET_VERTEX_DATA3F_M + 24 , "NV4097_SET_VERTEX_DATA3F_M + 24" }, - { NV4097_SET_VERTEX_DATA3F_M + 28 , "NV4097_SET_VERTEX_DATA3F_M + 28" }, - { NV4097_SET_VERTEX_DATA3F_M + 32 , "NV4097_SET_VERTEX_DATA3F_M + 32" }, - { NV4097_SET_VERTEX_DATA3F_M + 36 , "NV4097_SET_VERTEX_DATA3F_M + 36" }, - { NV4097_SET_VERTEX_DATA3F_M + 40 , "NV4097_SET_VERTEX_DATA3F_M + 40" }, - { NV4097_SET_VERTEX_DATA3F_M + 44 , "NV4097_SET_VERTEX_DATA3F_M + 44" }, - { NV4097_SET_VERTEX_DATA3F_M + 48 , "NV4097_SET_VERTEX_DATA3F_M + 48" }, - { NV4097_SET_VERTEX_DATA3F_M + 52 , "NV4097_SET_VERTEX_DATA3F_M + 52" }, - { NV4097_SET_VERTEX_DATA3F_M + 56 , "NV4097_SET_VERTEX_DATA3F_M + 56" }, - { NV4097_SET_VERTEX_DATA3F_M + 60 , "NV4097_SET_VERTEX_DATA3F_M + 60" }, - { NV4097_SET_VERTEX_DATA3F_M + 64 , "NV4097_SET_VERTEX_DATA3F_M + 64" }, - { NV4097_SET_VERTEX_DATA3F_M + 68 , "NV4097_SET_VERTEX_DATA3F_M + 68" }, - { NV4097_SET_VERTEX_DATA3F_M + 72 , "NV4097_SET_VERTEX_DATA3F_M + 72" }, - { NV4097_SET_VERTEX_DATA3F_M + 76 , "NV4097_SET_VERTEX_DATA3F_M + 76" }, - { NV4097_SET_VERTEX_DATA3F_M + 80 , "NV4097_SET_VERTEX_DATA3F_M + 80" }, - { NV4097_SET_VERTEX_DATA3F_M + 84 , "NV4097_SET_VERTEX_DATA3F_M + 84" }, - { NV4097_SET_VERTEX_DATA3F_M + 88 , "NV4097_SET_VERTEX_DATA3F_M + 88" }, - { NV4097_SET_VERTEX_DATA3F_M + 92 , "NV4097_SET_VERTEX_DATA3F_M + 92" }, - { NV4097_SET_VERTEX_DATA3F_M + 96 , "NV4097_SET_VERTEX_DATA3F_M + 96" }, - { NV4097_SET_VERTEX_DATA3F_M + 100 , "NV4097_SET_VERTEX_DATA3F_M + 100" }, - { NV4097_SET_VERTEX_DATA3F_M + 104 , "NV4097_SET_VERTEX_DATA3F_M + 104" }, - { NV4097_SET_VERTEX_DATA3F_M + 108 , "NV4097_SET_VERTEX_DATA3F_M + 108" }, - { NV4097_SET_VERTEX_DATA3F_M + 112 , "NV4097_SET_VERTEX_DATA3F_M + 112" }, - { NV4097_SET_VERTEX_DATA3F_M + 116 , "NV4097_SET_VERTEX_DATA3F_M + 116" }, - { NV4097_SET_VERTEX_DATA3F_M + 120 , "NV4097_SET_VERTEX_DATA3F_M + 120" }, - { NV4097_SET_VERTEX_DATA3F_M + 124 , "NV4097_SET_VERTEX_DATA3F_M + 124" }, - { NV4097_SET_VERTEX_DATA3F_M + 128 , "NV4097_SET_VERTEX_DATA3F_M + 128" }, - { NV4097_SET_VERTEX_DATA3F_M + 132 , "NV4097_SET_VERTEX_DATA3F_M + 132" }, - { NV4097_SET_VERTEX_DATA3F_M + 136 , "NV4097_SET_VERTEX_DATA3F_M + 136" }, - { NV4097_SET_VERTEX_DATA3F_M + 140 , "NV4097_SET_VERTEX_DATA3F_M + 140" }, - { NV4097_SET_VERTEX_DATA3F_M + 144 , "NV4097_SET_VERTEX_DATA3F_M + 144" }, - { NV4097_SET_VERTEX_DATA3F_M + 148 , "NV4097_SET_VERTEX_DATA3F_M + 148" }, - { NV4097_SET_VERTEX_DATA3F_M + 152 , "NV4097_SET_VERTEX_DATA3F_M + 152" }, - { NV4097_SET_VERTEX_DATA3F_M + 156 , "NV4097_SET_VERTEX_DATA3F_M + 156" }, - { NV4097_SET_VERTEX_DATA3F_M + 160 , "NV4097_SET_VERTEX_DATA3F_M + 160" }, - { NV4097_SET_VERTEX_DATA3F_M + 164 , "NV4097_SET_VERTEX_DATA3F_M + 164" }, - { NV4097_SET_VERTEX_DATA3F_M + 168 , "NV4097_SET_VERTEX_DATA3F_M + 168" }, - { NV4097_SET_VERTEX_DATA3F_M + 172 , "NV4097_SET_VERTEX_DATA3F_M + 172" }, - { NV4097_SET_VERTEX_DATA3F_M + 176 , "NV4097_SET_VERTEX_DATA3F_M + 176" }, - { NV4097_SET_VERTEX_DATA3F_M + 180 , "NV4097_SET_VERTEX_DATA3F_M + 180" }, - { NV4097_SET_VERTEX_DATA3F_M + 184 , "NV4097_SET_VERTEX_DATA3F_M + 184" }, - { NV4097_SET_VERTEX_DATA3F_M + 188 , "NV4097_SET_VERTEX_DATA3F_M + 188" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56" }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60 , "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60" }, - { NV4097_INVALIDATE_VERTEX_CACHE_FILE , "NV4097_INVALIDATE_VERTEX_CACHE_FILE" }, - { NV4097_INVALIDATE_VERTEX_FILE , "NV4097_INVALIDATE_VERTEX_FILE" }, - { NV4097_SET_VERTEX_DATA_BASE_OFFSET , "NV4097_SET_VERTEX_DATA_BASE_OFFSET" }, - { NV4097_SET_VERTEX_DATA_BASE_INDEX , "NV4097_SET_VERTEX_DATA_BASE_INDEX" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56" }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60 , "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60" }, - { NV4097_CLEAR_REPORT_VALUE , "NV4097_CLEAR_REPORT_VALUE" }, - { NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE , "NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE" }, - { NV4097_GET_REPORT , "NV4097_GET_REPORT" }, - { NV4097_SET_ZCULL_STATS_ENABLE , "NV4097_SET_ZCULL_STATS_ENABLE" }, - { NV4097_SET_BEGIN_END , "NV4097_SET_BEGIN_END" }, - { NV4097_ARRAY_ELEMENT16 , "NV4097_ARRAY_ELEMENT16" }, - { NV4097_ARRAY_ELEMENT32 , "NV4097_ARRAY_ELEMENT32" }, - { NV4097_DRAW_ARRAYS , "NV4097_DRAW_ARRAYS" }, - { NV4097_INLINE_ARRAY , "NV4097_INLINE_ARRAY" }, - { NV4097_SET_INDEX_ARRAY_ADDRESS , "NV4097_SET_INDEX_ARRAY_ADDRESS" }, - { NV4097_SET_INDEX_ARRAY_DMA , "NV4097_SET_INDEX_ARRAY_DMA" }, - { NV4097_DRAW_INDEX_ARRAY , "NV4097_DRAW_INDEX_ARRAY" }, - { NV4097_SET_FRONT_POLYGON_MODE , "NV4097_SET_FRONT_POLYGON_MODE" }, - { NV4097_SET_BACK_POLYGON_MODE , "NV4097_SET_BACK_POLYGON_MODE" }, - { NV4097_SET_CULL_FACE , "NV4097_SET_CULL_FACE" }, - { NV4097_SET_FRONT_FACE , "NV4097_SET_FRONT_FACE" }, - { NV4097_SET_POLY_SMOOTH_ENABLE , "NV4097_SET_POLY_SMOOTH_ENABLE" }, - { NV4097_SET_CULL_FACE_ENABLE , "NV4097_SET_CULL_FACE_ENABLE" }, - { NV4097_SET_TEXTURE_CONTROL3 , "NV4097_SET_TEXTURE_CONTROL3" }, - { NV4097_SET_TEXTURE_CONTROL3 + 4 , "NV4097_SET_TEXTURE_CONTROL3 + 4" }, - { NV4097_SET_TEXTURE_CONTROL3 + 8 , "NV4097_SET_TEXTURE_CONTROL3 + 8" }, - { NV4097_SET_TEXTURE_CONTROL3 + 12 , "NV4097_SET_TEXTURE_CONTROL3 + 12" }, - { NV4097_SET_TEXTURE_CONTROL3 + 16 , "NV4097_SET_TEXTURE_CONTROL3 + 16" }, - { NV4097_SET_TEXTURE_CONTROL3 + 20 , "NV4097_SET_TEXTURE_CONTROL3 + 20" }, - { NV4097_SET_TEXTURE_CONTROL3 + 24 , "NV4097_SET_TEXTURE_CONTROL3 + 24" }, - { NV4097_SET_TEXTURE_CONTROL3 + 28 , "NV4097_SET_TEXTURE_CONTROL3 + 28" }, - { NV4097_SET_TEXTURE_CONTROL3 + 32 , "NV4097_SET_TEXTURE_CONTROL3 + 32" }, - { NV4097_SET_TEXTURE_CONTROL3 + 36 , "NV4097_SET_TEXTURE_CONTROL3 + 36" }, - { NV4097_SET_TEXTURE_CONTROL3 + 40 , "NV4097_SET_TEXTURE_CONTROL3 + 40" }, - { NV4097_SET_TEXTURE_CONTROL3 + 44 , "NV4097_SET_TEXTURE_CONTROL3 + 44" }, - { NV4097_SET_TEXTURE_CONTROL3 + 48 , "NV4097_SET_TEXTURE_CONTROL3 + 48" }, - { NV4097_SET_TEXTURE_CONTROL3 + 52 , "NV4097_SET_TEXTURE_CONTROL3 + 52" }, - { NV4097_SET_TEXTURE_CONTROL3 + 56 , "NV4097_SET_TEXTURE_CONTROL3 + 56" }, - { NV4097_SET_TEXTURE_CONTROL3 + 60 , "NV4097_SET_TEXTURE_CONTROL3 + 60" }, - { NV4097_SET_VERTEX_DATA2F_M , "NV4097_SET_VERTEX_DATA2F_M" }, - { NV4097_SET_VERTEX_DATA2F_M + 4 , "NV4097_SET_VERTEX_DATA2F_M + 4" }, - { NV4097_SET_VERTEX_DATA2F_M + 8 , "NV4097_SET_VERTEX_DATA2F_M + 8" }, - { NV4097_SET_VERTEX_DATA2F_M + 12 , "NV4097_SET_VERTEX_DATA2F_M + 12" }, - { NV4097_SET_VERTEX_DATA2F_M + 16 , "NV4097_SET_VERTEX_DATA2F_M + 16" }, - { NV4097_SET_VERTEX_DATA2F_M + 20 , "NV4097_SET_VERTEX_DATA2F_M + 20" }, - { NV4097_SET_VERTEX_DATA2F_M + 24 , "NV4097_SET_VERTEX_DATA2F_M + 24" }, - { NV4097_SET_VERTEX_DATA2F_M + 28 , "NV4097_SET_VERTEX_DATA2F_M + 28" }, - { NV4097_SET_VERTEX_DATA2F_M + 32 , "NV4097_SET_VERTEX_DATA2F_M + 32" }, - { NV4097_SET_VERTEX_DATA2F_M + 36 , "NV4097_SET_VERTEX_DATA2F_M + 36" }, - { NV4097_SET_VERTEX_DATA2F_M + 40 , "NV4097_SET_VERTEX_DATA2F_M + 40" }, - { NV4097_SET_VERTEX_DATA2F_M + 44 , "NV4097_SET_VERTEX_DATA2F_M + 44" }, - { NV4097_SET_VERTEX_DATA2F_M + 48 , "NV4097_SET_VERTEX_DATA2F_M + 48" }, - { NV4097_SET_VERTEX_DATA2F_M + 52 , "NV4097_SET_VERTEX_DATA2F_M + 52" }, - { NV4097_SET_VERTEX_DATA2F_M + 56 , "NV4097_SET_VERTEX_DATA2F_M + 56" }, - { NV4097_SET_VERTEX_DATA2F_M + 60 , "NV4097_SET_VERTEX_DATA2F_M + 60" }, - { NV4097_SET_VERTEX_DATA2F_M + 64 , "NV4097_SET_VERTEX_DATA2F_M + 64" }, - { NV4097_SET_VERTEX_DATA2F_M + 68 , "NV4097_SET_VERTEX_DATA2F_M + 68" }, - { NV4097_SET_VERTEX_DATA2F_M + 72 , "NV4097_SET_VERTEX_DATA2F_M + 72" }, - { NV4097_SET_VERTEX_DATA2F_M + 76 , "NV4097_SET_VERTEX_DATA2F_M + 76" }, - { NV4097_SET_VERTEX_DATA2F_M + 80 , "NV4097_SET_VERTEX_DATA2F_M + 80" }, - { NV4097_SET_VERTEX_DATA2F_M + 84 , "NV4097_SET_VERTEX_DATA2F_M + 84" }, - { NV4097_SET_VERTEX_DATA2F_M + 88 , "NV4097_SET_VERTEX_DATA2F_M + 88" }, - { NV4097_SET_VERTEX_DATA2F_M + 92 , "NV4097_SET_VERTEX_DATA2F_M + 92" }, - { NV4097_SET_VERTEX_DATA2F_M + 96 , "NV4097_SET_VERTEX_DATA2F_M + 96" }, - { NV4097_SET_VERTEX_DATA2F_M + 100 , "NV4097_SET_VERTEX_DATA2F_M + 100" }, - { NV4097_SET_VERTEX_DATA2F_M + 104 , "NV4097_SET_VERTEX_DATA2F_M + 104" }, - { NV4097_SET_VERTEX_DATA2F_M + 108 , "NV4097_SET_VERTEX_DATA2F_M + 108" }, - { NV4097_SET_VERTEX_DATA2F_M + 112 , "NV4097_SET_VERTEX_DATA2F_M + 112" }, - { NV4097_SET_VERTEX_DATA2F_M + 116 , "NV4097_SET_VERTEX_DATA2F_M + 116" }, - { NV4097_SET_VERTEX_DATA2F_M + 120 , "NV4097_SET_VERTEX_DATA2F_M + 120" }, - { NV4097_SET_VERTEX_DATA2F_M + 124 , "NV4097_SET_VERTEX_DATA2F_M + 124" }, - { NV4097_SET_VERTEX_DATA2S_M , "NV4097_SET_VERTEX_DATA2S_M" }, - { NV4097_SET_VERTEX_DATA2S_M + 4 , "NV4097_SET_VERTEX_DATA2S_M + 4" }, - { NV4097_SET_VERTEX_DATA2S_M + 8 , "NV4097_SET_VERTEX_DATA2S_M + 8" }, - { NV4097_SET_VERTEX_DATA2S_M + 12 , "NV4097_SET_VERTEX_DATA2S_M + 12" }, - { NV4097_SET_VERTEX_DATA2S_M + 16 , "NV4097_SET_VERTEX_DATA2S_M + 16" }, - { NV4097_SET_VERTEX_DATA2S_M + 20 , "NV4097_SET_VERTEX_DATA2S_M + 20" }, - { NV4097_SET_VERTEX_DATA2S_M + 24 , "NV4097_SET_VERTEX_DATA2S_M + 24" }, - { NV4097_SET_VERTEX_DATA2S_M + 28 , "NV4097_SET_VERTEX_DATA2S_M + 28" }, - { NV4097_SET_VERTEX_DATA2S_M + 32 , "NV4097_SET_VERTEX_DATA2S_M + 32" }, - { NV4097_SET_VERTEX_DATA2S_M + 36 , "NV4097_SET_VERTEX_DATA2S_M + 36" }, - { NV4097_SET_VERTEX_DATA2S_M + 40 , "NV4097_SET_VERTEX_DATA2S_M + 40" }, - { NV4097_SET_VERTEX_DATA2S_M + 44 , "NV4097_SET_VERTEX_DATA2S_M + 44" }, - { NV4097_SET_VERTEX_DATA2S_M + 48 , "NV4097_SET_VERTEX_DATA2S_M + 48" }, - { NV4097_SET_VERTEX_DATA2S_M + 52 , "NV4097_SET_VERTEX_DATA2S_M + 52" }, - { NV4097_SET_VERTEX_DATA2S_M + 56 , "NV4097_SET_VERTEX_DATA2S_M + 56" }, - { NV4097_SET_VERTEX_DATA2S_M + 60 , "NV4097_SET_VERTEX_DATA2S_M + 60" }, - { NV4097_SET_VERTEX_DATA4UB_M , "NV4097_SET_VERTEX_DATA4UB_M" }, - { NV4097_SET_VERTEX_DATA4UB_M + 4 , "NV4097_SET_VERTEX_DATA4UB_M + 4" }, - { NV4097_SET_VERTEX_DATA4UB_M + 8 , "NV4097_SET_VERTEX_DATA4UB_M + 8" }, - { NV4097_SET_VERTEX_DATA4UB_M + 12 , "NV4097_SET_VERTEX_DATA4UB_M + 12" }, - { NV4097_SET_VERTEX_DATA4UB_M + 16 , "NV4097_SET_VERTEX_DATA4UB_M + 16" }, - { NV4097_SET_VERTEX_DATA4UB_M + 20 , "NV4097_SET_VERTEX_DATA4UB_M + 20" }, - { NV4097_SET_VERTEX_DATA4UB_M + 24 , "NV4097_SET_VERTEX_DATA4UB_M + 24" }, - { NV4097_SET_VERTEX_DATA4UB_M + 28 , "NV4097_SET_VERTEX_DATA4UB_M + 28" }, - { NV4097_SET_VERTEX_DATA4UB_M + 32 , "NV4097_SET_VERTEX_DATA4UB_M + 32" }, - { NV4097_SET_VERTEX_DATA4UB_M + 36 , "NV4097_SET_VERTEX_DATA4UB_M + 36" }, - { NV4097_SET_VERTEX_DATA4UB_M + 40 , "NV4097_SET_VERTEX_DATA4UB_M + 40" }, - { NV4097_SET_VERTEX_DATA4UB_M + 44 , "NV4097_SET_VERTEX_DATA4UB_M + 44" }, - { NV4097_SET_VERTEX_DATA4UB_M + 48 , "NV4097_SET_VERTEX_DATA4UB_M + 48" }, - { NV4097_SET_VERTEX_DATA4UB_M + 52 , "NV4097_SET_VERTEX_DATA4UB_M + 52" }, - { NV4097_SET_VERTEX_DATA4UB_M + 56 , "NV4097_SET_VERTEX_DATA4UB_M + 56" }, - { NV4097_SET_VERTEX_DATA4UB_M + 60 , "NV4097_SET_VERTEX_DATA4UB_M + 60" }, - { NV4097_SET_VERTEX_DATA4S_M , "NV4097_SET_VERTEX_DATA4S_M" }, - { NV4097_SET_VERTEX_DATA4S_M + 4 , "NV4097_SET_VERTEX_DATA4S_M + 4" }, - { NV4097_SET_VERTEX_DATA4S_M + 8 , "NV4097_SET_VERTEX_DATA4S_M + 8" }, - { NV4097_SET_VERTEX_DATA4S_M + 12 , "NV4097_SET_VERTEX_DATA4S_M + 12" }, - { NV4097_SET_VERTEX_DATA4S_M + 16 , "NV4097_SET_VERTEX_DATA4S_M + 16" }, - { NV4097_SET_VERTEX_DATA4S_M + 20 , "NV4097_SET_VERTEX_DATA4S_M + 20" }, - { NV4097_SET_VERTEX_DATA4S_M + 24 , "NV4097_SET_VERTEX_DATA4S_M + 24" }, - { NV4097_SET_VERTEX_DATA4S_M + 28 , "NV4097_SET_VERTEX_DATA4S_M + 28" }, - { NV4097_SET_VERTEX_DATA4S_M + 32 , "NV4097_SET_VERTEX_DATA4S_M + 32" }, - { NV4097_SET_VERTEX_DATA4S_M + 36 , "NV4097_SET_VERTEX_DATA4S_M + 36" }, - { NV4097_SET_VERTEX_DATA4S_M + 40 , "NV4097_SET_VERTEX_DATA4S_M + 40" }, - { NV4097_SET_VERTEX_DATA4S_M + 44 , "NV4097_SET_VERTEX_DATA4S_M + 44" }, - { NV4097_SET_VERTEX_DATA4S_M + 48 , "NV4097_SET_VERTEX_DATA4S_M + 48" }, - { NV4097_SET_VERTEX_DATA4S_M + 52 , "NV4097_SET_VERTEX_DATA4S_M + 52" }, - { NV4097_SET_VERTEX_DATA4S_M + 56 , "NV4097_SET_VERTEX_DATA4S_M + 56" }, - { NV4097_SET_VERTEX_DATA4S_M + 60 , "NV4097_SET_VERTEX_DATA4S_M + 60" }, - { NV4097_SET_VERTEX_DATA4S_M + 64 , "NV4097_SET_VERTEX_DATA4S_M + 64" }, - { NV4097_SET_VERTEX_DATA4S_M + 68 , "NV4097_SET_VERTEX_DATA4S_M + 68" }, - { NV4097_SET_VERTEX_DATA4S_M + 72 , "NV4097_SET_VERTEX_DATA4S_M + 72" }, - { NV4097_SET_VERTEX_DATA4S_M + 76 , "NV4097_SET_VERTEX_DATA4S_M + 76" }, - { NV4097_SET_VERTEX_DATA4S_M + 80 , "NV4097_SET_VERTEX_DATA4S_M + 80" }, - { NV4097_SET_VERTEX_DATA4S_M + 84 , "NV4097_SET_VERTEX_DATA4S_M + 84" }, - { NV4097_SET_VERTEX_DATA4S_M + 88 , "NV4097_SET_VERTEX_DATA4S_M + 88" }, - { NV4097_SET_VERTEX_DATA4S_M + 92 , "NV4097_SET_VERTEX_DATA4S_M + 92" }, - { NV4097_SET_VERTEX_DATA4S_M + 96 , "NV4097_SET_VERTEX_DATA4S_M + 96" }, - { NV4097_SET_VERTEX_DATA4S_M + 100 , "NV4097_SET_VERTEX_DATA4S_M + 100" }, - { NV4097_SET_VERTEX_DATA4S_M + 104 , "NV4097_SET_VERTEX_DATA4S_M + 104" }, - { NV4097_SET_VERTEX_DATA4S_M + 108 , "NV4097_SET_VERTEX_DATA4S_M + 108" }, - { NV4097_SET_VERTEX_DATA4S_M + 112 , "NV4097_SET_VERTEX_DATA4S_M + 112" }, - { NV4097_SET_VERTEX_DATA4S_M + 116 , "NV4097_SET_VERTEX_DATA4S_M + 116" }, - { NV4097_SET_VERTEX_DATA4S_M + 120 , "NV4097_SET_VERTEX_DATA4S_M + 120" }, - { NV4097_SET_VERTEX_DATA4S_M + 124 , "NV4097_SET_VERTEX_DATA4S_M + 124" }, - { NV4097_SET_TEXTURE_OFFSET , "NV4097_SET_TEXTURE_OFFSET" }, - { NV4097_SET_TEXTURE_FORMAT , "NV4097_SET_TEXTURE_FORMAT" }, - { NV4097_SET_TEXTURE_ADDRESS , "NV4097_SET_TEXTURE_ADDRESS" }, - { NV4097_SET_TEXTURE_CONTROL0 , "NV4097_SET_TEXTURE_CONTROL0" }, - { NV4097_SET_TEXTURE_CONTROL1 , "NV4097_SET_TEXTURE_CONTROL1" }, - { NV4097_SET_TEXTURE_FILTER , "NV4097_SET_TEXTURE_FILTER" }, - { NV4097_SET_TEXTURE_IMAGE_RECT , "NV4097_SET_TEXTURE_IMAGE_RECT" }, - { NV4097_SET_TEXTURE_BORDER_COLOR , "NV4097_SET_TEXTURE_BORDER_COLOR" }, - { NV4097_SET_TEXTURE_OFFSET + 0x20 , "NV4097_SET_TEXTURE_OFFSET + 0x20" }, - { NV4097_SET_TEXTURE_FORMAT + 0x20 , "NV4097_SET_TEXTURE_FORMAT + 0x20" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x20 , "NV4097_SET_TEXTURE_ADDRESS + 0x20" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x20 , "NV4097_SET_TEXTURE_CONTROL0 + 0x20" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x20 , "NV4097_SET_TEXTURE_CONTROL1 + 0x20" }, - { NV4097_SET_TEXTURE_FILTER + 0x20 , "NV4097_SET_TEXTURE_FILTER + 0x20" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x20 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x20" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x20 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x20" }, - { NV4097_SET_TEXTURE_OFFSET + 0x40 , "NV4097_SET_TEXTURE_OFFSET + 0x40" }, - { NV4097_SET_TEXTURE_FORMAT + 0x40 , "NV4097_SET_TEXTURE_FORMAT + 0x40" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x40 , "NV4097_SET_TEXTURE_ADDRESS + 0x40" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x40 , "NV4097_SET_TEXTURE_CONTROL0 + 0x40" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x40 , "NV4097_SET_TEXTURE_CONTROL1 + 0x40" }, - { NV4097_SET_TEXTURE_FILTER + 0x40 , "NV4097_SET_TEXTURE_FILTER + 0x40" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x40 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x40" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x40 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x40" }, - { NV4097_SET_TEXTURE_OFFSET + 0x60 , "NV4097_SET_TEXTURE_OFFSET + 0x60" }, - { NV4097_SET_TEXTURE_FORMAT + 0x60 , "NV4097_SET_TEXTURE_FORMAT + 0x60" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x60 , "NV4097_SET_TEXTURE_ADDRESS + 0x60" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x60 , "NV4097_SET_TEXTURE_CONTROL0 + 0x60" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x60 , "NV4097_SET_TEXTURE_CONTROL1 + 0x60" }, - { NV4097_SET_TEXTURE_FILTER + 0x60 , "NV4097_SET_TEXTURE_FILTER + 0x60" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x60 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x60" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x60 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x60" }, - { NV4097_SET_TEXTURE_OFFSET + 0x80 , "NV4097_SET_TEXTURE_OFFSET + 0x80" }, - { NV4097_SET_TEXTURE_FORMAT + 0x80 , "NV4097_SET_TEXTURE_FORMAT + 0x80" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x80 , "NV4097_SET_TEXTURE_ADDRESS + 0x80" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x80 , "NV4097_SET_TEXTURE_CONTROL0 + 0x80" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x80 , "NV4097_SET_TEXTURE_CONTROL1 + 0x80" }, - { NV4097_SET_TEXTURE_FILTER + 0x80 , "NV4097_SET_TEXTURE_FILTER + 0x80" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x80 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x80" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x80 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x80" }, - { NV4097_SET_TEXTURE_OFFSET + 0xa0 , "NV4097_SET_TEXTURE_OFFSET + 0xa0" }, - { NV4097_SET_TEXTURE_FORMAT + 0xa0 , "NV4097_SET_TEXTURE_FORMAT + 0xa0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0xa0 , "NV4097_SET_TEXTURE_ADDRESS + 0xa0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0xa0 , "NV4097_SET_TEXTURE_CONTROL0 + 0xa0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0xa0 , "NV4097_SET_TEXTURE_CONTROL1 + 0xa0" }, - { NV4097_SET_TEXTURE_FILTER + 0xa0 , "NV4097_SET_TEXTURE_FILTER + 0xa0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0" }, - { NV4097_SET_TEXTURE_OFFSET + 0xc0 , "NV4097_SET_TEXTURE_OFFSET + 0xc0" }, - { NV4097_SET_TEXTURE_FORMAT + 0xc0 , "NV4097_SET_TEXTURE_FORMAT + 0xc0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0xc0 , "NV4097_SET_TEXTURE_ADDRESS + 0xc0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0xc0 , "NV4097_SET_TEXTURE_CONTROL0 + 0xc0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0xc0 , "NV4097_SET_TEXTURE_CONTROL1 + 0xc0" }, - { NV4097_SET_TEXTURE_FILTER + 0xc0 , "NV4097_SET_TEXTURE_FILTER + 0xc0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0" }, - { NV4097_SET_TEXTURE_OFFSET + 0xe0 , "NV4097_SET_TEXTURE_OFFSET + 0xe0" }, - { NV4097_SET_TEXTURE_FORMAT + 0xe0 , "NV4097_SET_TEXTURE_FORMAT + 0xe0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0xe0 , "NV4097_SET_TEXTURE_ADDRESS + 0xe0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0xe0 , "NV4097_SET_TEXTURE_CONTROL0 + 0xe0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0xe0 , "NV4097_SET_TEXTURE_CONTROL1 + 0xe0" }, - { NV4097_SET_TEXTURE_FILTER + 0xe0 , "NV4097_SET_TEXTURE_FILTER + 0xe0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0" }, - { NV4097_SET_TEXTURE_OFFSET + 0x100 , "NV4097_SET_TEXTURE_OFFSET + 0x100" }, - { NV4097_SET_TEXTURE_FORMAT + 0x100 , "NV4097_SET_TEXTURE_FORMAT + 0x100" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x100 , "NV4097_SET_TEXTURE_ADDRESS + 0x100" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x100 , "NV4097_SET_TEXTURE_CONTROL0 + 0x100" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x100 , "NV4097_SET_TEXTURE_CONTROL1 + 0x100" }, - { NV4097_SET_TEXTURE_FILTER + 0x100 , "NV4097_SET_TEXTURE_FILTER + 0x100" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x100 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x100" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x100 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x100" }, - { NV4097_SET_TEXTURE_OFFSET + 0x120 , "NV4097_SET_TEXTURE_OFFSET + 0x120" }, - { NV4097_SET_TEXTURE_FORMAT + 0x120 , "NV4097_SET_TEXTURE_FORMAT + 0x120" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x120 , "NV4097_SET_TEXTURE_ADDRESS + 0x120" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x120 , "NV4097_SET_TEXTURE_CONTROL0 + 0x120" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x120 , "NV4097_SET_TEXTURE_CONTROL1 + 0x120" }, - { NV4097_SET_TEXTURE_FILTER + 0x120 , "NV4097_SET_TEXTURE_FILTER + 0x120" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x120 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x120" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x120 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x120" }, - { NV4097_SET_TEXTURE_OFFSET + 0x140 , "NV4097_SET_TEXTURE_OFFSET + 0x140" }, - { NV4097_SET_TEXTURE_FORMAT + 0x140 , "NV4097_SET_TEXTURE_FORMAT + 0x140" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x140 , "NV4097_SET_TEXTURE_ADDRESS + 0x140" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x140 , "NV4097_SET_TEXTURE_CONTROL0 + 0x140" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x140 , "NV4097_SET_TEXTURE_CONTROL1 + 0x140" }, - { NV4097_SET_TEXTURE_FILTER + 0x140 , "NV4097_SET_TEXTURE_FILTER + 0x140" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x140 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x140" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x140 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x140" }, - { NV4097_SET_TEXTURE_OFFSET + 0x160 , "NV4097_SET_TEXTURE_OFFSET + 0x160" }, - { NV4097_SET_TEXTURE_FORMAT + 0x160 , "NV4097_SET_TEXTURE_FORMAT + 0x160" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x160 , "NV4097_SET_TEXTURE_ADDRESS + 0x160" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x160 , "NV4097_SET_TEXTURE_CONTROL0 + 0x160" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x160 , "NV4097_SET_TEXTURE_CONTROL1 + 0x160" }, - { NV4097_SET_TEXTURE_FILTER + 0x160 , "NV4097_SET_TEXTURE_FILTER + 0x160" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x160 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x160" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x160 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x160" }, - { NV4097_SET_TEXTURE_OFFSET + 0x180 , "NV4097_SET_TEXTURE_OFFSET + 0x180" }, - { NV4097_SET_TEXTURE_FORMAT + 0x180 , "NV4097_SET_TEXTURE_FORMAT + 0x180" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x180 , "NV4097_SET_TEXTURE_ADDRESS + 0x180" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x180 , "NV4097_SET_TEXTURE_CONTROL0 + 0x180" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x180 , "NV4097_SET_TEXTURE_CONTROL1 + 0x180" }, - { NV4097_SET_TEXTURE_FILTER + 0x180 , "NV4097_SET_TEXTURE_FILTER + 0x180" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x180 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x180" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x180 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x180" }, - { NV4097_SET_TEXTURE_OFFSET + 0x1a0 , "NV4097_SET_TEXTURE_OFFSET + 0x1a0" }, - { NV4097_SET_TEXTURE_FORMAT + 0x1a0 , "NV4097_SET_TEXTURE_FORMAT + 0x1a0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x1a0 , "NV4097_SET_TEXTURE_ADDRESS + 0x1a0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x1a0 , "NV4097_SET_TEXTURE_CONTROL0 + 0x1a0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x1a0 , "NV4097_SET_TEXTURE_CONTROL1 + 0x1a0" }, - { NV4097_SET_TEXTURE_FILTER + 0x1a0 , "NV4097_SET_TEXTURE_FILTER + 0x1a0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0" }, - { NV4097_SET_TEXTURE_OFFSET + 0x1c0 , "NV4097_SET_TEXTURE_OFFSET + 0x1c0" }, - { NV4097_SET_TEXTURE_FORMAT + 0x1c0 , "NV4097_SET_TEXTURE_FORMAT + 0x1c0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x1c0 , "NV4097_SET_TEXTURE_ADDRESS + 0x1c0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x1c0 , "NV4097_SET_TEXTURE_CONTROL0 + 0x1c0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x1c0 , "NV4097_SET_TEXTURE_CONTROL1 + 0x1c0" }, - { NV4097_SET_TEXTURE_FILTER + 0x1c0 , "NV4097_SET_TEXTURE_FILTER + 0x1c0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0" }, - { NV4097_SET_TEXTURE_OFFSET + 0x1e0 , "NV4097_SET_TEXTURE_OFFSET + 0x1e0" }, - { NV4097_SET_TEXTURE_FORMAT + 0x1e0 , "NV4097_SET_TEXTURE_FORMAT + 0x1e0" }, - { NV4097_SET_TEXTURE_ADDRESS + 0x1e0 , "NV4097_SET_TEXTURE_ADDRESS + 0x1e0" }, - { NV4097_SET_TEXTURE_CONTROL0 + 0x1e0 , "NV4097_SET_TEXTURE_CONTROL0 + 0x1e0" }, - { NV4097_SET_TEXTURE_CONTROL1 + 0x1e0 , "NV4097_SET_TEXTURE_CONTROL1 + 0x1e0" }, - { NV4097_SET_TEXTURE_FILTER + 0x1e0 , "NV4097_SET_TEXTURE_FILTER + 0x1e0" }, - { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0 , "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0" }, - { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0 , "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0" }, - { NV4097_SET_VERTEX_DATA4F_M , "NV4097_SET_VERTEX_DATA4F_M" }, - { NV4097_SET_VERTEX_DATA4F_M + 4 , "NV4097_SET_VERTEX_DATA4F_M + 4" }, - { NV4097_SET_VERTEX_DATA4F_M + 8 , "NV4097_SET_VERTEX_DATA4F_M + 8" }, - { NV4097_SET_VERTEX_DATA4F_M + 12 , "NV4097_SET_VERTEX_DATA4F_M + 12" }, - { NV4097_SET_VERTEX_DATA4F_M + 16 , "NV4097_SET_VERTEX_DATA4F_M + 16" }, - { NV4097_SET_VERTEX_DATA4F_M + 20 , "NV4097_SET_VERTEX_DATA4F_M + 20" }, - { NV4097_SET_VERTEX_DATA4F_M + 24 , "NV4097_SET_VERTEX_DATA4F_M + 24" }, - { NV4097_SET_VERTEX_DATA4F_M + 28 , "NV4097_SET_VERTEX_DATA4F_M + 28" }, - { NV4097_SET_VERTEX_DATA4F_M + 32 , "NV4097_SET_VERTEX_DATA4F_M + 32" }, - { NV4097_SET_VERTEX_DATA4F_M + 36 , "NV4097_SET_VERTEX_DATA4F_M + 36" }, - { NV4097_SET_VERTEX_DATA4F_M + 40 , "NV4097_SET_VERTEX_DATA4F_M + 40" }, - { NV4097_SET_VERTEX_DATA4F_M + 44 , "NV4097_SET_VERTEX_DATA4F_M + 44" }, - { NV4097_SET_VERTEX_DATA4F_M + 48 , "NV4097_SET_VERTEX_DATA4F_M + 48" }, - { NV4097_SET_VERTEX_DATA4F_M + 52 , "NV4097_SET_VERTEX_DATA4F_M + 52" }, - { NV4097_SET_VERTEX_DATA4F_M + 56 , "NV4097_SET_VERTEX_DATA4F_M + 56" }, - { NV4097_SET_VERTEX_DATA4F_M + 60 , "NV4097_SET_VERTEX_DATA4F_M + 60" }, - { NV4097_SET_VERTEX_DATA4F_M + 64 , "NV4097_SET_VERTEX_DATA4F_M + 64" }, - { NV4097_SET_VERTEX_DATA4F_M + 68 , "NV4097_SET_VERTEX_DATA4F_M + 68" }, - { NV4097_SET_VERTEX_DATA4F_M + 72 , "NV4097_SET_VERTEX_DATA4F_M + 72" }, - { NV4097_SET_VERTEX_DATA4F_M + 76 , "NV4097_SET_VERTEX_DATA4F_M + 76" }, - { NV4097_SET_VERTEX_DATA4F_M + 80 , "NV4097_SET_VERTEX_DATA4F_M + 80" }, - { NV4097_SET_VERTEX_DATA4F_M + 84 , "NV4097_SET_VERTEX_DATA4F_M + 84" }, - { NV4097_SET_VERTEX_DATA4F_M + 88 , "NV4097_SET_VERTEX_DATA4F_M + 88" }, - { NV4097_SET_VERTEX_DATA4F_M + 92 , "NV4097_SET_VERTEX_DATA4F_M + 92" }, - { NV4097_SET_VERTEX_DATA4F_M + 96 , "NV4097_SET_VERTEX_DATA4F_M + 96" }, - { NV4097_SET_VERTEX_DATA4F_M + 100 , "NV4097_SET_VERTEX_DATA4F_M + 100" }, - { NV4097_SET_VERTEX_DATA4F_M + 104 , "NV4097_SET_VERTEX_DATA4F_M + 104" }, - { NV4097_SET_VERTEX_DATA4F_M + 108 , "NV4097_SET_VERTEX_DATA4F_M + 108" }, - { NV4097_SET_VERTEX_DATA4F_M + 112 , "NV4097_SET_VERTEX_DATA4F_M + 112" }, - { NV4097_SET_VERTEX_DATA4F_M + 116 , "NV4097_SET_VERTEX_DATA4F_M + 116" }, - { NV4097_SET_VERTEX_DATA4F_M + 120 , "NV4097_SET_VERTEX_DATA4F_M + 120" }, - { NV4097_SET_VERTEX_DATA4F_M + 124 , "NV4097_SET_VERTEX_DATA4F_M + 124" }, - { NV4097_SET_VERTEX_DATA4F_M + 128 , "NV4097_SET_VERTEX_DATA4F_M + 128" }, - { NV4097_SET_VERTEX_DATA4F_M + 132 , "NV4097_SET_VERTEX_DATA4F_M + 132" }, - { NV4097_SET_VERTEX_DATA4F_M + 136 , "NV4097_SET_VERTEX_DATA4F_M + 136" }, - { NV4097_SET_VERTEX_DATA4F_M + 140 , "NV4097_SET_VERTEX_DATA4F_M + 140" }, - { NV4097_SET_VERTEX_DATA4F_M + 144 , "NV4097_SET_VERTEX_DATA4F_M + 144" }, - { NV4097_SET_VERTEX_DATA4F_M + 148 , "NV4097_SET_VERTEX_DATA4F_M + 148" }, - { NV4097_SET_VERTEX_DATA4F_M + 152 , "NV4097_SET_VERTEX_DATA4F_M + 152" }, - { NV4097_SET_VERTEX_DATA4F_M + 156 , "NV4097_SET_VERTEX_DATA4F_M + 156" }, - { NV4097_SET_VERTEX_DATA4F_M + 160 , "NV4097_SET_VERTEX_DATA4F_M + 160" }, - { NV4097_SET_VERTEX_DATA4F_M + 164 , "NV4097_SET_VERTEX_DATA4F_M + 164" }, - { NV4097_SET_VERTEX_DATA4F_M + 168 , "NV4097_SET_VERTEX_DATA4F_M + 168" }, - { NV4097_SET_VERTEX_DATA4F_M + 172 , "NV4097_SET_VERTEX_DATA4F_M + 172" }, - { NV4097_SET_VERTEX_DATA4F_M + 176 , "NV4097_SET_VERTEX_DATA4F_M + 176" }, - { NV4097_SET_VERTEX_DATA4F_M + 180 , "NV4097_SET_VERTEX_DATA4F_M + 180" }, - { NV4097_SET_VERTEX_DATA4F_M + 184 , "NV4097_SET_VERTEX_DATA4F_M + 184" }, - { NV4097_SET_VERTEX_DATA4F_M + 188 , "NV4097_SET_VERTEX_DATA4F_M + 188" }, - { NV4097_SET_VERTEX_DATA4F_M + 192 , "NV4097_SET_VERTEX_DATA4F_M + 192" }, - { NV4097_SET_VERTEX_DATA4F_M + 196 , "NV4097_SET_VERTEX_DATA4F_M + 196" }, - { NV4097_SET_VERTEX_DATA4F_M + 200 , "NV4097_SET_VERTEX_DATA4F_M + 200" }, - { NV4097_SET_VERTEX_DATA4F_M + 204 , "NV4097_SET_VERTEX_DATA4F_M + 204" }, - { NV4097_SET_VERTEX_DATA4F_M + 208 , "NV4097_SET_VERTEX_DATA4F_M + 208" }, - { NV4097_SET_VERTEX_DATA4F_M + 212 , "NV4097_SET_VERTEX_DATA4F_M + 212" }, - { NV4097_SET_VERTEX_DATA4F_M + 216 , "NV4097_SET_VERTEX_DATA4F_M + 216" }, - { NV4097_SET_VERTEX_DATA4F_M + 220 , "NV4097_SET_VERTEX_DATA4F_M + 220" }, - { NV4097_SET_VERTEX_DATA4F_M + 224 , "NV4097_SET_VERTEX_DATA4F_M + 224" }, - { NV4097_SET_VERTEX_DATA4F_M + 228 , "NV4097_SET_VERTEX_DATA4F_M + 228" }, - { NV4097_SET_VERTEX_DATA4F_M + 232 , "NV4097_SET_VERTEX_DATA4F_M + 232" }, - { NV4097_SET_VERTEX_DATA4F_M + 236 , "NV4097_SET_VERTEX_DATA4F_M + 236" }, - { NV4097_SET_VERTEX_DATA4F_M + 240 , "NV4097_SET_VERTEX_DATA4F_M + 240" }, - { NV4097_SET_VERTEX_DATA4F_M + 244 , "NV4097_SET_VERTEX_DATA4F_M + 244" }, - { NV4097_SET_VERTEX_DATA4F_M + 248 , "NV4097_SET_VERTEX_DATA4F_M + 248" }, - { NV4097_SET_VERTEX_DATA4F_M + 252 , "NV4097_SET_VERTEX_DATA4F_M + 252" }, - { NV4097_SET_SHADER_CONTROL , "NV4097_SET_SHADER_CONTROL" }, - { NV4097_SET_SEMAPHORE_OFFSET , "NV4097_SET_SEMAPHORE_OFFSET" }, - { NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE , "NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE" }, - { NV4097_TEXTURE_READ_SEMAPHORE_RELEASE , "NV4097_TEXTURE_READ_SEMAPHORE_RELEASE" }, - { NV4097_SET_ZMIN_MAX_CONTROL , "NV4097_SET_ZMIN_MAX_CONTROL" }, - { NV4097_SET_ANTI_ALIASING_CONTROL , "NV4097_SET_ANTI_ALIASING_CONTROL" }, - { NV4097_SET_ZCULL_EN , "NV4097_SET_ZCULL_EN" }, - { NV4097_SET_SHADER_WINDOW , "NV4097_SET_SHADER_WINDOW" }, - { NV4097_SET_ZSTENCIL_CLEAR_VALUE , "NV4097_SET_ZSTENCIL_CLEAR_VALUE" }, - { NV4097_SET_COLOR_CLEAR_VALUE , "NV4097_SET_COLOR_CLEAR_VALUE" }, - { NV4097_CLEAR_SURFACE , "NV4097_CLEAR_SURFACE" }, - { NV4097_SET_RESTART_INDEX_ENABLE , "NV4097_SET_RESTART_INDEX_ENABLE" }, - { NV4097_SET_RESTART_INDEX , "NV4097_SET_RESTART_INDEX" }, - { NV4097_SET_LINE_STIPPLE , "NV4097_SET_LINE_STIPPLE" }, - { NV4097_SET_LINE_STIPPLE_PATTERN , "NV4097_SET_LINE_STIPPLE_PATTERN" }, - { NV4097_SET_VERTEX_DATA1F_M , "NV4097_SET_VERTEX_DATA1F_M" }, - { NV4097_SET_VERTEX_DATA1F_M + 4 , "NV4097_SET_VERTEX_DATA1F_M + 4" }, - { NV4097_SET_VERTEX_DATA1F_M + 8 , "NV4097_SET_VERTEX_DATA1F_M + 8" }, - { NV4097_SET_VERTEX_DATA1F_M + 12 , "NV4097_SET_VERTEX_DATA1F_M + 12" }, - { NV4097_SET_VERTEX_DATA1F_M + 16 , "NV4097_SET_VERTEX_DATA1F_M + 16" }, - { NV4097_SET_VERTEX_DATA1F_M + 20 , "NV4097_SET_VERTEX_DATA1F_M + 20" }, - { NV4097_SET_VERTEX_DATA1F_M + 24 , "NV4097_SET_VERTEX_DATA1F_M + 24" }, - { NV4097_SET_VERTEX_DATA1F_M + 28 , "NV4097_SET_VERTEX_DATA1F_M + 28" }, - { NV4097_SET_VERTEX_DATA1F_M + 32 , "NV4097_SET_VERTEX_DATA1F_M + 32" }, - { NV4097_SET_VERTEX_DATA1F_M + 36 , "NV4097_SET_VERTEX_DATA1F_M + 36" }, - { NV4097_SET_VERTEX_DATA1F_M + 40 , "NV4097_SET_VERTEX_DATA1F_M + 40" }, - { NV4097_SET_VERTEX_DATA1F_M + 44 , "NV4097_SET_VERTEX_DATA1F_M + 44" }, - { NV4097_SET_VERTEX_DATA1F_M + 48 , "NV4097_SET_VERTEX_DATA1F_M + 48" }, - { NV4097_SET_VERTEX_DATA1F_M + 52 , "NV4097_SET_VERTEX_DATA1F_M + 52" }, - { NV4097_SET_VERTEX_DATA1F_M + 56 , "NV4097_SET_VERTEX_DATA1F_M + 56" }, - { NV4097_SET_VERTEX_DATA1F_M + 60 , "NV4097_SET_VERTEX_DATA1F_M + 60" }, - { NV4097_SET_RENDER_ENABLE , "NV4097_SET_RENDER_ENABLE" }, - { NV4097_SET_TRANSFORM_PROGRAM_LOAD , "NV4097_SET_TRANSFORM_PROGRAM_LOAD" }, - { NV4097_SET_TRANSFORM_PROGRAM_START , "NV4097_SET_TRANSFORM_PROGRAM_START" }, - { NV4097_SET_ZCULL_CONTROL0 , "NV4097_SET_ZCULL_CONTROL0" }, - { NV4097_SET_ZCULL_CONTROL1 , "NV4097_SET_ZCULL_CONTROL1" }, - { NV4097_SET_SCULL_CONTROL , "NV4097_SET_SCULL_CONTROL" }, - { NV4097_SET_POINT_SIZE , "NV4097_SET_POINT_SIZE" }, - { NV4097_SET_POINT_PARAMS_ENABLE , "NV4097_SET_POINT_PARAMS_ENABLE" }, - { NV4097_SET_POINT_SPRITE_CONTROL , "NV4097_SET_POINT_SPRITE_CONTROL" }, - { NV4097_SET_TRANSFORM_TIMEOUT , "NV4097_SET_TRANSFORM_TIMEOUT" }, - { NV4097_SET_TRANSFORM_CONSTANT_LOAD , "NV4097_SET_TRANSFORM_CONSTANT_LOAD" }, - { NV4097_SET_FREQUENCY_DIVIDER_OPERATION , "NV4097_SET_FREQUENCY_DIVIDER_OPERATION" }, - { NV4097_SET_ATTRIB_COLOR, "NV4097_SET_ATTRIB_COLOR" }, - { NV4097_SET_ATTRIB_TEX_COORD, "NV4097_SET_ATTRIB_TEX_COORD" }, - { NV4097_SET_ATTRIB_TEX_COORD_EX, "NV4097_SET_ATTRIB_TEX_COORD_EX" }, - { NV4097_SET_ATTRIB_UCLIP0, "NV4097_SET_ATTRIB_UCLIP0" }, - { NV4097_SET_ATTRIB_UCLIP1, "NV4097_SET_ATTRIB_UCLIP1" }, - { NV4097_INVALIDATE_L2, "NV4097_INVALIDATE_L2" }, - { NV4097_SET_REDUCE_DST_COLOR, "NV4097_SET_REDUCE_DST_COLOR" }, - { NV4097_SET_NO_PARANOID_TEXTURE_FETCHES, "NV4097_SET_NO_PARANOID_TEXTURE_FETCHES" }, - { NV4097_SET_SHADER_PACKER, "NV4097_SET_SHADER_PACKER" }, - { NV4097_SET_VERTEX_ATTRIB_INPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_INPUT_MASK" }, - { NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK" }, - { NV4097_SET_TRANSFORM_BRANCH_BITS, "NV4097_SET_TRANSFORM_BRANCH_BITS" } - }; - for (auto& s: METHOD_NAME_LIST) +enum Method +{ + CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000, + CELL_GCM_METHOD_FLAG_JUMP = 0x20000000, + CELL_GCM_METHOD_FLAG_CALL = 0x00000002, + CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, +}; + +namespace rsx +{ + template + static auto make_command(u32 start_register, T... values) -> std::array { - if (s.id == id) - return s.name; + return{ (start_register << 2) | u32(sizeof...(values) << 18), u32(values)... }; } - return fmt::format("unknown/illegal method [0x%08x]", id); -} + static u32 make_jump(u32 offset) + { + return CELL_GCM_METHOD_FLAG_JUMP | offset; + } + + template + static size_t make_command(vm::ps3::ptr &dst, u32 start_register, T... values) + { + for (u32 command : { (start_register << 2) | u32(sizeof...(values) << 18), u32(values)... }) + { + *dst++ = command; + } + + return sizeof...(values) + 1; + } + + template + static size_t make_jump(vm::ps3::ptr &dst, u32 offset) + { + *dst++ = make_jump(offset); + return 1; + } + + static const std::string get_method_name(const u32 id) + { + static const std::unordered_map methods = + { + { NV4097_NO_OPERATION, "NV4097_NO_OPERATION" }, + { NV4097_NOTIFY, "NV4097_NOTIFY" }, + { NV4097_WAIT_FOR_IDLE, "NV4097_WAIT_FOR_IDLE" }, + { NV4097_PM_TRIGGER, "NV4097_PM_TRIGGER" }, + { NV4097_SET_CONTEXT_DMA_NOTIFIES, "NV4097_SET_CONTEXT_DMA_NOTIFIES" }, + { NV4097_SET_CONTEXT_DMA_A, "NV4097_SET_CONTEXT_DMA_A" }, + { NV4097_SET_CONTEXT_DMA_B, "NV4097_SET_CONTEXT_DMA_B" }, + { NV4097_SET_CONTEXT_DMA_COLOR_B, "NV4097_SET_CONTEXT_DMA_COLOR_B" }, + { NV4097_SET_CONTEXT_DMA_STATE, "NV4097_SET_CONTEXT_DMA_STATE" }, + { NV4097_SET_CONTEXT_DMA_COLOR_A, "NV4097_SET_CONTEXT_DMA_COLOR_A" }, + { NV4097_SET_CONTEXT_DMA_ZETA, "NV4097_SET_CONTEXT_DMA_ZETA" }, + { NV4097_SET_CONTEXT_DMA_VERTEX_A, "NV4097_SET_CONTEXT_DMA_VERTEX_A" }, + { NV4097_SET_CONTEXT_DMA_VERTEX_B, "NV4097_SET_CONTEXT_DMA_VERTEX_B" }, + { NV4097_SET_CONTEXT_DMA_SEMAPHORE, "NV4097_SET_CONTEXT_DMA_SEMAPHORE" }, + { NV4097_SET_CONTEXT_DMA_REPORT, "NV4097_SET_CONTEXT_DMA_REPORT" }, + { NV4097_SET_CONTEXT_DMA_CLIP_ID, "NV4097_SET_CONTEXT_DMA_CLIP_ID" }, + { NV4097_SET_CONTEXT_DMA_CULL_DATA, "NV4097_SET_CONTEXT_DMA_CULL_DATA" }, + { NV4097_SET_CONTEXT_DMA_COLOR_C, "NV4097_SET_CONTEXT_DMA_COLOR_C" }, + { NV4097_SET_CONTEXT_DMA_COLOR_D, "NV4097_SET_CONTEXT_DMA_COLOR_D" }, + { NV4097_SET_SURFACE_CLIP_HORIZONTAL, "NV4097_SET_SURFACE_CLIP_HORIZONTAL" }, + { NV4097_SET_SURFACE_CLIP_VERTICAL, "NV4097_SET_SURFACE_CLIP_VERTICAL" }, + { NV4097_SET_SURFACE_FORMAT, "NV4097_SET_SURFACE_FORMAT" }, + { NV4097_SET_SURFACE_PITCH_A, "NV4097_SET_SURFACE_PITCH_A" }, + { NV4097_SET_SURFACE_COLOR_AOFFSET, "NV4097_SET_SURFACE_COLOR_AOFFSET" }, + { NV4097_SET_SURFACE_ZETA_OFFSET, "NV4097_SET_SURFACE_ZETA_OFFSET" }, + { NV4097_SET_SURFACE_COLOR_BOFFSET, "NV4097_SET_SURFACE_COLOR_BOFFSET" }, + { NV4097_SET_SURFACE_PITCH_B, "NV4097_SET_SURFACE_PITCH_B" }, + { NV4097_SET_SURFACE_COLOR_TARGET, "NV4097_SET_SURFACE_COLOR_TARGET" }, + { NV4097_SET_SURFACE_PITCH_Z, "NV4097_SET_SURFACE_PITCH_Z" }, + { NV4097_INVALIDATE_ZCULL, "NV4097_INVALIDATE_ZCULL" }, + { NV4097_SET_CYLINDRICAL_WRAP, "NV4097_SET_CYLINDRICAL_WRAP" }, + { NV4097_SET_CYLINDRICAL_WRAP1, "NV4097_SET_CYLINDRICAL_WRAP1" }, + { NV4097_SET_SURFACE_PITCH_C, "NV4097_SET_SURFACE_PITCH_C" }, + { NV4097_SET_SURFACE_PITCH_D, "NV4097_SET_SURFACE_PITCH_D" }, + { NV4097_SET_SURFACE_COLOR_COFFSET, "NV4097_SET_SURFACE_COLOR_COFFSET" }, + { NV4097_SET_SURFACE_COLOR_DOFFSET, "NV4097_SET_SURFACE_COLOR_DOFFSET" }, + { NV4097_SET_WINDOW_OFFSET, "NV4097_SET_WINDOW_OFFSET" }, + { NV4097_SET_DITHER_ENABLE, "NV4097_SET_DITHER_ENABLE" }, + { NV4097_SET_ALPHA_TEST_ENABLE, "NV4097_SET_ALPHA_TEST_ENABLE" }, + { NV4097_SET_ALPHA_FUNC, "NV4097_SET_ALPHA_FUNC" }, + { NV4097_SET_ALPHA_REF, "NV4097_SET_ALPHA_REF" }, + { NV4097_SET_BLEND_ENABLE, "NV4097_SET_BLEND_ENABLE" }, + { NV4097_SET_BLEND_FUNC_SFACTOR, "NV4097_SET_BLEND_FUNC_SFACTOR" }, + { NV4097_SET_BLEND_FUNC_DFACTOR, "NV4097_SET_BLEND_FUNC_DFACTOR" }, + { NV4097_SET_BLEND_COLOR, "NV4097_SET_BLEND_COLOR" }, + { NV4097_SET_BLEND_EQUATION, "NV4097_SET_BLEND_EQUATION" }, + { NV4097_SET_COLOR_MASK, "NV4097_SET_COLOR_MASK" }, + { NV4097_SET_STENCIL_TEST_ENABLE, "NV4097_SET_STENCIL_TEST_ENABLE" }, + { NV4097_SET_STENCIL_MASK, "NV4097_SET_STENCIL_MASK" }, + { NV4097_SET_STENCIL_FUNC, "NV4097_SET_STENCIL_FUNC" }, + { NV4097_SET_STENCIL_FUNC_REF, "NV4097_SET_STENCIL_FUNC_REF" }, + { NV4097_SET_STENCIL_FUNC_MASK, "NV4097_SET_STENCIL_FUNC_MASK" }, + { NV4097_SET_STENCIL_OP_FAIL, "NV4097_SET_STENCIL_OP_FAIL" }, + { NV4097_SET_STENCIL_OP_ZFAIL, "NV4097_SET_STENCIL_OP_ZFAIL" }, + { NV4097_SET_STENCIL_OP_ZPASS, "NV4097_SET_STENCIL_OP_ZPASS" }, + { NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE, "NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE" }, + { NV4097_SET_BACK_STENCIL_MASK, "NV4097_SET_BACK_STENCIL_MASK" }, + { NV4097_SET_BACK_STENCIL_FUNC, "NV4097_SET_BACK_STENCIL_FUNC" }, + { NV4097_SET_BACK_STENCIL_FUNC_REF, "NV4097_SET_BACK_STENCIL_FUNC_REF" }, + { NV4097_SET_BACK_STENCIL_FUNC_MASK, "NV4097_SET_BACK_STENCIL_FUNC_MASK" }, + { NV4097_SET_BACK_STENCIL_OP_FAIL, "NV4097_SET_BACK_STENCIL_OP_FAIL" }, + { NV4097_SET_BACK_STENCIL_OP_ZFAIL, "NV4097_SET_BACK_STENCIL_OP_ZFAIL" }, + { NV4097_SET_BACK_STENCIL_OP_ZPASS, "NV4097_SET_BACK_STENCIL_OP_ZPASS" }, + { NV4097_SET_SHADE_MODE, "NV4097_SET_SHADE_MODE" }, + { NV4097_SET_BLEND_ENABLE_MRT, "NV4097_SET_BLEND_ENABLE_MRT" }, + { NV4097_SET_COLOR_MASK_MRT, "NV4097_SET_COLOR_MASK_MRT" }, + { NV4097_SET_LOGIC_OP_ENABLE, "NV4097_SET_LOGIC_OP_ENABLE" }, + { NV4097_SET_LOGIC_OP, "NV4097_SET_LOGIC_OP" }, + { NV4097_SET_BLEND_COLOR2, "NV4097_SET_BLEND_COLOR2" }, + { NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE, "NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE" }, + { NV4097_SET_DEPTH_BOUNDS_MIN, "NV4097_SET_DEPTH_BOUNDS_MIN" }, + { NV4097_SET_DEPTH_BOUNDS_MAX, "NV4097_SET_DEPTH_BOUNDS_MAX" }, + { NV4097_SET_CLIP_MIN, "NV4097_SET_CLIP_MIN" }, + { NV4097_SET_CLIP_MAX, "NV4097_SET_CLIP_MAX" }, + { NV4097_SET_CONTROL0, "NV4097_SET_CONTROL0" }, + { NV4097_SET_LINE_WIDTH, "NV4097_SET_LINE_WIDTH" }, + { NV4097_SET_LINE_SMOOTH_ENABLE, "NV4097_SET_LINE_SMOOTH_ENABLE" }, + { NV4097_SET_ANISO_SPREAD, "NV4097_SET_ANISO_SPREAD" }, + { NV4097_SET_ANISO_SPREAD + 4 / 4, "NV4097_SET_ANISO_SPREAD + 4" }, + { NV4097_SET_ANISO_SPREAD + 8 / 4, "NV4097_SET_ANISO_SPREAD + 8" }, + { NV4097_SET_ANISO_SPREAD + 12 / 4, "NV4097_SET_ANISO_SPREAD + 12" }, + { NV4097_SET_ANISO_SPREAD + 16 / 4, "NV4097_SET_ANISO_SPREAD + 16" }, + { NV4097_SET_ANISO_SPREAD + 20 / 4, "NV4097_SET_ANISO_SPREAD + 20" }, + { NV4097_SET_ANISO_SPREAD + 24 / 4, "NV4097_SET_ANISO_SPREAD + 24" }, + { NV4097_SET_ANISO_SPREAD + 28 / 4, "NV4097_SET_ANISO_SPREAD + 28" }, + { NV4097_SET_ANISO_SPREAD + 32 / 4, "NV4097_SET_ANISO_SPREAD + 32" }, + { NV4097_SET_ANISO_SPREAD + 36 / 4, "NV4097_SET_ANISO_SPREAD + 36" }, + { NV4097_SET_ANISO_SPREAD + 40 / 4, "NV4097_SET_ANISO_SPREAD + 40" }, + { NV4097_SET_ANISO_SPREAD + 44 / 4, "NV4097_SET_ANISO_SPREAD + 44" }, + { NV4097_SET_ANISO_SPREAD + 48 / 4, "NV4097_SET_ANISO_SPREAD + 48" }, + { NV4097_SET_ANISO_SPREAD + 52 / 4, "NV4097_SET_ANISO_SPREAD + 52" }, + { NV4097_SET_ANISO_SPREAD + 56 / 4, "NV4097_SET_ANISO_SPREAD + 56" }, + { NV4097_SET_ANISO_SPREAD + 60 / 4, "NV4097_SET_ANISO_SPREAD + 60" }, + { NV4097_SET_SCISSOR_HORIZONTAL, "NV4097_SET_SCISSOR_HORIZONTAL" }, + { NV4097_SET_SCISSOR_VERTICAL, "NV4097_SET_SCISSOR_VERTICAL" }, + { NV4097_SET_FOG_MODE, "NV4097_SET_FOG_MODE" }, + { NV4097_SET_FOG_PARAMS, "NV4097_SET_FOG_PARAMS" }, + { NV4097_SET_FOG_PARAMS + 4 / 4, "NV4097_SET_FOG_PARAMS + 4" }, + { NV4097_SET_FOG_PARAMS + 8 / 4, "NV4097_SET_FOG_PARAMS + 8" }, + { NV4097_SET_SHADER_PROGRAM, "NV4097_SET_SHADER_PROGRAM" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET, "NV4097_SET_VERTEX_TEXTURE_OFFSET" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT, "NV4097_SET_VERTEX_TEXTURE_FORMAT" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS, "NV4097_SET_VERTEX_TEXTURE_ADDRESS" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0, "NV4097_SET_VERTEX_TEXTURE_CONTROL0" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3, "NV4097_SET_VERTEX_TEXTURE_CONTROL3" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER, "NV4097_SET_VERTEX_TEXTURE_FILTER" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20 / 4, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x20" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40 / 4, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x40" }, + { NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_OFFSET + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_FORMAT + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_ADDRESS + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL0 + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_CONTROL3 + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_FILTER + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + 0x60" }, + { NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60 / 4, "NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + 0x60" }, + { NV4097_SET_VIEWPORT_HORIZONTAL, "NV4097_SET_VIEWPORT_HORIZONTAL" }, + { NV4097_SET_VIEWPORT_VERTICAL, "NV4097_SET_VIEWPORT_VERTICAL" }, + { NV4097_SET_VIEWPORT_OFFSET, "NV4097_SET_VIEWPORT_OFFSET" }, + { NV4097_SET_VIEWPORT_SCALE, "NV4097_SET_VIEWPORT_SCALE" }, + { NV4097_SET_POLY_OFFSET_LINE_ENABLE, "NV4097_SET_POLY_OFFSET_LINE_ENABLE" }, + { NV4097_SET_POLY_OFFSET_FILL_ENABLE, "NV4097_SET_POLY_OFFSET_FILL_ENABLE" }, + { NV4097_SET_DEPTH_FUNC, "NV4097_SET_DEPTH_FUNC" }, + { NV4097_SET_DEPTH_MASK, "NV4097_SET_DEPTH_MASK" }, + { NV4097_SET_DEPTH_TEST_ENABLE, "NV4097_SET_DEPTH_TEST_ENABLE" }, + { NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR, "NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR" }, + { NV4097_SET_POLYGON_OFFSET_BIAS, "NV4097_SET_POLYGON_OFFSET_BIAS" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M, "NV4097_SET_VERTEX_DATA_SCALED4S_M" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 4 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 4" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 8 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 8" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 12 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 12" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 16 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 16" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 20 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 20" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 24 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 24" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 28 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 28" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 32 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 32" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 36 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 36" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 40, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 40" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 44 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 44" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 48 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 48" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 52 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 52" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 56 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 56" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 60 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 60" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 64 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 64" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 68 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 68" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 72 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 72" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 76 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 76" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 80 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 80" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 84 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 84" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 88 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 88" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 92 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 92" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 96 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 96" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 100 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 100" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 104 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 104" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 108 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 108" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 112 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 112" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 116 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 116" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 120 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 120" }, + { NV4097_SET_VERTEX_DATA_SCALED4S_M + 124 / 4, "NV4097_SET_VERTEX_DATA_SCALED4S_M + 124" }, + { NV4097_SET_TEXTURE_CONTROL2, "NV4097_SET_TEXTURE_CONTROL2" }, + { NV4097_SET_TEXTURE_CONTROL2 + 4 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 4" }, + { NV4097_SET_TEXTURE_CONTROL2 + 8 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 8" }, + { NV4097_SET_TEXTURE_CONTROL2 + 12 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 12" }, + { NV4097_SET_TEXTURE_CONTROL2 + 16 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 16" }, + { NV4097_SET_TEXTURE_CONTROL2 + 20 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 20" }, + { NV4097_SET_TEXTURE_CONTROL2 + 24 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 24" }, + { NV4097_SET_TEXTURE_CONTROL2 + 28 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 28" }, + { NV4097_SET_TEXTURE_CONTROL2 + 32 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 32" }, + { NV4097_SET_TEXTURE_CONTROL2 + 36 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 36" }, + { NV4097_SET_TEXTURE_CONTROL2 + 40 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 40" }, + { NV4097_SET_TEXTURE_CONTROL2 + 44 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 44" }, + { NV4097_SET_TEXTURE_CONTROL2 + 48 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 48" }, + { NV4097_SET_TEXTURE_CONTROL2 + 52 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 52" }, + { NV4097_SET_TEXTURE_CONTROL2 + 56 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 56" }, + { NV4097_SET_TEXTURE_CONTROL2 + 60 / 4, "NV4097_SET_TEXTURE_CONTROL2 + 60" }, + { NV4097_SET_TEX_COORD_CONTROL, "NV4097_SET_TEX_COORD_CONTROL" }, + { NV4097_SET_TEX_COORD_CONTROL + 4 / 4, "NV4097_SET_TEX_COORD_CONTROL + 4" }, + { NV4097_SET_TEX_COORD_CONTROL + 8 / 4, "NV4097_SET_TEX_COORD_CONTROL + 8" }, + { NV4097_SET_TEX_COORD_CONTROL + 12 / 4, "NV4097_SET_TEX_COORD_CONTROL + 12" }, + { NV4097_SET_TEX_COORD_CONTROL + 16 / 4, "NV4097_SET_TEX_COORD_CONTROL + 16" }, + { NV4097_SET_TEX_COORD_CONTROL + 20 / 4, "NV4097_SET_TEX_COORD_CONTROL + 20" }, + { NV4097_SET_TEX_COORD_CONTROL + 24 / 4, "NV4097_SET_TEX_COORD_CONTROL + 24" }, + { NV4097_SET_TEX_COORD_CONTROL + 28 / 4, "NV4097_SET_TEX_COORD_CONTROL + 28" }, + { NV4097_SET_TEX_COORD_CONTROL + 32 / 4, "NV4097_SET_TEX_COORD_CONTROL + 32" }, + { NV4097_SET_TEX_COORD_CONTROL + 36 / 4, "NV4097_SET_TEX_COORD_CONTROL + 36" }, + { NV4097_SET_TRANSFORM_PROGRAM, "NV4097_SET_TRANSFORM_PROGRAM" }, + { NV4097_SET_TRANSFORM_PROGRAM + 4 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 4" }, + { NV4097_SET_TRANSFORM_PROGRAM + 8 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 8" }, + { NV4097_SET_TRANSFORM_PROGRAM + 12 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 12" }, + { NV4097_SET_TRANSFORM_PROGRAM + 16 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 16" }, + { NV4097_SET_TRANSFORM_PROGRAM + 20 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 20" }, + { NV4097_SET_TRANSFORM_PROGRAM + 24 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 24" }, + { NV4097_SET_TRANSFORM_PROGRAM + 28 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 28" }, + { NV4097_SET_TRANSFORM_PROGRAM + 32 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 32" }, + { NV4097_SET_TRANSFORM_PROGRAM + 36 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 36" }, + { NV4097_SET_TRANSFORM_PROGRAM + 40 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 40" }, + { NV4097_SET_TRANSFORM_PROGRAM + 44 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 44" }, + { NV4097_SET_TRANSFORM_PROGRAM + 48 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 48" }, + { NV4097_SET_TRANSFORM_PROGRAM + 52 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 52" }, + { NV4097_SET_TRANSFORM_PROGRAM + 56 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 56" }, + { NV4097_SET_TRANSFORM_PROGRAM + 60 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 60" }, + { NV4097_SET_TRANSFORM_PROGRAM + 64 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 64" }, + { NV4097_SET_TRANSFORM_PROGRAM + 68 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 68" }, + { NV4097_SET_TRANSFORM_PROGRAM + 72 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 72" }, + { NV4097_SET_TRANSFORM_PROGRAM + 76 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 76" }, + { NV4097_SET_TRANSFORM_PROGRAM + 80 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 80" }, + { NV4097_SET_TRANSFORM_PROGRAM + 84 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 84" }, + { NV4097_SET_TRANSFORM_PROGRAM + 88 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 88" }, + { NV4097_SET_TRANSFORM_PROGRAM + 92 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 92" }, + { NV4097_SET_TRANSFORM_PROGRAM + 96 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 96" }, + { NV4097_SET_TRANSFORM_PROGRAM + 100 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 100" }, + { NV4097_SET_TRANSFORM_PROGRAM + 104 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 104" }, + { NV4097_SET_TRANSFORM_PROGRAM + 108 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 108" }, + { NV4097_SET_TRANSFORM_PROGRAM + 112 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 112" }, + { NV4097_SET_TRANSFORM_PROGRAM + 116 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 116" }, + { NV4097_SET_TRANSFORM_PROGRAM + 120 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 120" }, + { NV4097_SET_TRANSFORM_PROGRAM + 124 / 4, "NV4097_SET_TRANSFORM_PROGRAM + 124" }, + { NV4097_SET_TWO_SIDE_LIGHT_EN, "NV4097_SET_TWO_SIDE_LIGHT_EN" }, + { NV4097_CLEAR_ZCULL_SURFACE, "NV4097_CLEAR_ZCULL_SURFACE" }, + { NV4097_SET_USER_CLIP_PLANE_CONTROL, "NV4097_SET_USER_CLIP_PLANE_CONTROL" }, + { NV4097_SET_POLYGON_STIPPLE, "NV4097_SET_POLYGON_STIPPLE" }, + { NV4097_SET_POLYGON_STIPPLE_PATTERN, "NV4097_SET_POLYGON_STIPPLE_PATTERN" }, + { NV4097_SET_VERTEX_DATA3F_M, "NV4097_SET_VERTEX_DATA3F_M" }, + { NV4097_SET_VERTEX_DATA3F_M + 4 / 4, "NV4097_SET_VERTEX_DATA3F_M + 4" }, + { NV4097_SET_VERTEX_DATA3F_M + 8 / 4, "NV4097_SET_VERTEX_DATA3F_M + 8" }, + { NV4097_SET_VERTEX_DATA3F_M + 12 / 4, "NV4097_SET_VERTEX_DATA3F_M + 12" }, + { NV4097_SET_VERTEX_DATA3F_M + 16 / 4, "NV4097_SET_VERTEX_DATA3F_M + 16" }, + { NV4097_SET_VERTEX_DATA3F_M + 20 / 4, "NV4097_SET_VERTEX_DATA3F_M + 20" }, + { NV4097_SET_VERTEX_DATA3F_M + 24 / 4, "NV4097_SET_VERTEX_DATA3F_M + 24" }, + { NV4097_SET_VERTEX_DATA3F_M + 28 / 4, "NV4097_SET_VERTEX_DATA3F_M + 28" }, + { NV4097_SET_VERTEX_DATA3F_M + 32 / 4, "NV4097_SET_VERTEX_DATA3F_M + 32" }, + { NV4097_SET_VERTEX_DATA3F_M + 36 / 4, "NV4097_SET_VERTEX_DATA3F_M + 36" }, + { NV4097_SET_VERTEX_DATA3F_M + 40 / 4, "NV4097_SET_VERTEX_DATA3F_M + 40" }, + { NV4097_SET_VERTEX_DATA3F_M + 44 / 4, "NV4097_SET_VERTEX_DATA3F_M + 44" }, + { NV4097_SET_VERTEX_DATA3F_M + 48 / 4, "NV4097_SET_VERTEX_DATA3F_M + 48" }, + { NV4097_SET_VERTEX_DATA3F_M + 52 / 4, "NV4097_SET_VERTEX_DATA3F_M + 52" }, + { NV4097_SET_VERTEX_DATA3F_M + 56 / 4, "NV4097_SET_VERTEX_DATA3F_M + 56" }, + { NV4097_SET_VERTEX_DATA3F_M + 60 / 4, "NV4097_SET_VERTEX_DATA3F_M + 60" }, + { NV4097_SET_VERTEX_DATA3F_M + 64 / 4, "NV4097_SET_VERTEX_DATA3F_M + 64" }, + { NV4097_SET_VERTEX_DATA3F_M + 68 / 4, "NV4097_SET_VERTEX_DATA3F_M + 68" }, + { NV4097_SET_VERTEX_DATA3F_M + 72 / 4, "NV4097_SET_VERTEX_DATA3F_M + 72" }, + { NV4097_SET_VERTEX_DATA3F_M + 76 / 4, "NV4097_SET_VERTEX_DATA3F_M + 76" }, + { NV4097_SET_VERTEX_DATA3F_M + 80 / 4, "NV4097_SET_VERTEX_DATA3F_M + 80" }, + { NV4097_SET_VERTEX_DATA3F_M + 84 / 4, "NV4097_SET_VERTEX_DATA3F_M + 84" }, + { NV4097_SET_VERTEX_DATA3F_M + 88 / 4, "NV4097_SET_VERTEX_DATA3F_M + 88" }, + { NV4097_SET_VERTEX_DATA3F_M + 92 / 4, "NV4097_SET_VERTEX_DATA3F_M + 92" }, + { NV4097_SET_VERTEX_DATA3F_M + 96 / 4, "NV4097_SET_VERTEX_DATA3F_M + 96" }, + { NV4097_SET_VERTEX_DATA3F_M + 100 / 4, "NV4097_SET_VERTEX_DATA3F_M + 100" }, + { NV4097_SET_VERTEX_DATA3F_M + 104 / 4, "NV4097_SET_VERTEX_DATA3F_M + 104" }, + { NV4097_SET_VERTEX_DATA3F_M + 108 / 4, "NV4097_SET_VERTEX_DATA3F_M + 108" }, + { NV4097_SET_VERTEX_DATA3F_M + 112 / 4, "NV4097_SET_VERTEX_DATA3F_M + 112" }, + { NV4097_SET_VERTEX_DATA3F_M + 116 / 4, "NV4097_SET_VERTEX_DATA3F_M + 116" }, + { NV4097_SET_VERTEX_DATA3F_M + 120 / 4, "NV4097_SET_VERTEX_DATA3F_M + 120" }, + { NV4097_SET_VERTEX_DATA3F_M + 124 / 4, "NV4097_SET_VERTEX_DATA3F_M + 124" }, + { NV4097_SET_VERTEX_DATA3F_M + 128 / 4, "NV4097_SET_VERTEX_DATA3F_M + 128" }, + { NV4097_SET_VERTEX_DATA3F_M + 132 / 4, "NV4097_SET_VERTEX_DATA3F_M + 132" }, + { NV4097_SET_VERTEX_DATA3F_M + 136 / 4, "NV4097_SET_VERTEX_DATA3F_M + 136" }, + { NV4097_SET_VERTEX_DATA3F_M + 140 / 4, "NV4097_SET_VERTEX_DATA3F_M + 140" }, + { NV4097_SET_VERTEX_DATA3F_M + 144 / 4, "NV4097_SET_VERTEX_DATA3F_M + 144" }, + { NV4097_SET_VERTEX_DATA3F_M + 148 / 4, "NV4097_SET_VERTEX_DATA3F_M + 148" }, + { NV4097_SET_VERTEX_DATA3F_M + 152 / 4, "NV4097_SET_VERTEX_DATA3F_M + 152" }, + { NV4097_SET_VERTEX_DATA3F_M + 156 / 4, "NV4097_SET_VERTEX_DATA3F_M + 156" }, + { NV4097_SET_VERTEX_DATA3F_M + 160 / 4, "NV4097_SET_VERTEX_DATA3F_M + 160" }, + { NV4097_SET_VERTEX_DATA3F_M + 164 / 4, "NV4097_SET_VERTEX_DATA3F_M + 164" }, + { NV4097_SET_VERTEX_DATA3F_M + 168 / 4, "NV4097_SET_VERTEX_DATA3F_M + 168" }, + { NV4097_SET_VERTEX_DATA3F_M + 172 / 4, "NV4097_SET_VERTEX_DATA3F_M + 172" }, + { NV4097_SET_VERTEX_DATA3F_M + 176 / 4, "NV4097_SET_VERTEX_DATA3F_M + 176" }, + { NV4097_SET_VERTEX_DATA3F_M + 180 / 4, "NV4097_SET_VERTEX_DATA3F_M + 180" }, + { NV4097_SET_VERTEX_DATA3F_M + 184 / 4, "NV4097_SET_VERTEX_DATA3F_M + 184" }, + { NV4097_SET_VERTEX_DATA3F_M + 188 / 4, "NV4097_SET_VERTEX_DATA3F_M + 188" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 16" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 20" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 24" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 28" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 32" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 36" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 40" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 44" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 48" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 52" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 56" }, + { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 60" }, + { NV4097_INVALIDATE_VERTEX_CACHE_FILE, "NV4097_INVALIDATE_VERTEX_CACHE_FILE" }, + { NV4097_INVALIDATE_VERTEX_FILE, "NV4097_INVALIDATE_VERTEX_FILE" }, + { NV4097_SET_VERTEX_DATA_BASE_OFFSET, "NV4097_SET_VERTEX_DATA_BASE_OFFSET" }, + { NV4097_SET_VERTEX_DATA_BASE_INDEX, "NV4097_SET_VERTEX_DATA_BASE_INDEX" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 16" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 20" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 24" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 28" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 32" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 36" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 40" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 44" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 48" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 52" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 56" }, + { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60 / 4, "NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 60" }, + { NV4097_CLEAR_REPORT_VALUE, "NV4097_CLEAR_REPORT_VALUE" }, + { NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE, "NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE" }, + { NV4097_GET_REPORT, "NV4097_GET_REPORT" }, + { NV4097_SET_ZCULL_STATS_ENABLE, "NV4097_SET_ZCULL_STATS_ENABLE" }, + { NV4097_SET_BEGIN_END, "NV4097_SET_BEGIN_END" }, + { NV4097_ARRAY_ELEMENT16, "NV4097_ARRAY_ELEMENT16" }, + { NV4097_ARRAY_ELEMENT32, "NV4097_ARRAY_ELEMENT32" }, + { NV4097_DRAW_ARRAYS, "NV4097_DRAW_ARRAYS" }, + { NV4097_INLINE_ARRAY, "NV4097_INLINE_ARRAY" }, + { NV4097_SET_INDEX_ARRAY_ADDRESS, "NV4097_SET_INDEX_ARRAY_ADDRESS" }, + { NV4097_SET_INDEX_ARRAY_DMA, "NV4097_SET_INDEX_ARRAY_DMA" }, + { NV4097_DRAW_INDEX_ARRAY, "NV4097_DRAW_INDEX_ARRAY" }, + { NV4097_SET_FRONT_POLYGON_MODE, "NV4097_SET_FRONT_POLYGON_MODE" }, + { NV4097_SET_BACK_POLYGON_MODE, "NV4097_SET_BACK_POLYGON_MODE" }, + { NV4097_SET_CULL_FACE, "NV4097_SET_CULL_FACE" }, + { NV4097_SET_FRONT_FACE, "NV4097_SET_FRONT_FACE" }, + { NV4097_SET_POLY_SMOOTH_ENABLE, "NV4097_SET_POLY_SMOOTH_ENABLE" }, + { NV4097_SET_CULL_FACE_ENABLE, "NV4097_SET_CULL_FACE_ENABLE" }, + { NV4097_SET_TEXTURE_CONTROL3, "NV4097_SET_TEXTURE_CONTROL3" }, + { NV4097_SET_TEXTURE_CONTROL3 + 4 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 4" }, + { NV4097_SET_TEXTURE_CONTROL3 + 8 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 8" }, + { NV4097_SET_TEXTURE_CONTROL3 + 12 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 12" }, + { NV4097_SET_TEXTURE_CONTROL3 + 16 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 16" }, + { NV4097_SET_TEXTURE_CONTROL3 + 20 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 20" }, + { NV4097_SET_TEXTURE_CONTROL3 + 24 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 24" }, + { NV4097_SET_TEXTURE_CONTROL3 + 28 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 28" }, + { NV4097_SET_TEXTURE_CONTROL3 + 32 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 32" }, + { NV4097_SET_TEXTURE_CONTROL3 + 36 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 36" }, + { NV4097_SET_TEXTURE_CONTROL3 + 40 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 40" }, + { NV4097_SET_TEXTURE_CONTROL3 + 44 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 44" }, + { NV4097_SET_TEXTURE_CONTROL3 + 48 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 48" }, + { NV4097_SET_TEXTURE_CONTROL3 + 52 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 52" }, + { NV4097_SET_TEXTURE_CONTROL3 + 56 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 56" }, + { NV4097_SET_TEXTURE_CONTROL3 + 60 / 4, "NV4097_SET_TEXTURE_CONTROL3 + 60" }, + { NV4097_SET_VERTEX_DATA2F_M, "NV4097_SET_VERTEX_DATA2F_M" }, + { NV4097_SET_VERTEX_DATA2F_M + 4 / 4, "NV4097_SET_VERTEX_DATA2F_M + 4" }, + { NV4097_SET_VERTEX_DATA2F_M + 8 / 4, "NV4097_SET_VERTEX_DATA2F_M + 8" }, + { NV4097_SET_VERTEX_DATA2F_M + 12 / 4, "NV4097_SET_VERTEX_DATA2F_M + 12" }, + { NV4097_SET_VERTEX_DATA2F_M + 16 / 4, "NV4097_SET_VERTEX_DATA2F_M + 16" }, + { NV4097_SET_VERTEX_DATA2F_M + 20 / 4, "NV4097_SET_VERTEX_DATA2F_M + 20" }, + { NV4097_SET_VERTEX_DATA2F_M + 24 / 4, "NV4097_SET_VERTEX_DATA2F_M + 24" }, + { NV4097_SET_VERTEX_DATA2F_M + 28 / 4, "NV4097_SET_VERTEX_DATA2F_M + 28" }, + { NV4097_SET_VERTEX_DATA2F_M + 32 / 4, "NV4097_SET_VERTEX_DATA2F_M + 32" }, + { NV4097_SET_VERTEX_DATA2F_M + 36 / 4, "NV4097_SET_VERTEX_DATA2F_M + 36" }, + { NV4097_SET_VERTEX_DATA2F_M + 40 / 4, "NV4097_SET_VERTEX_DATA2F_M + 40" }, + { NV4097_SET_VERTEX_DATA2F_M + 44 / 4, "NV4097_SET_VERTEX_DATA2F_M + 44" }, + { NV4097_SET_VERTEX_DATA2F_M + 48 / 4, "NV4097_SET_VERTEX_DATA2F_M + 48" }, + { NV4097_SET_VERTEX_DATA2F_M + 52 / 4, "NV4097_SET_VERTEX_DATA2F_M + 52" }, + { NV4097_SET_VERTEX_DATA2F_M + 56 / 4, "NV4097_SET_VERTEX_DATA2F_M + 56" }, + { NV4097_SET_VERTEX_DATA2F_M + 60 / 4, "NV4097_SET_VERTEX_DATA2F_M + 60" }, + { NV4097_SET_VERTEX_DATA2F_M + 64 / 4, "NV4097_SET_VERTEX_DATA2F_M + 64" }, + { NV4097_SET_VERTEX_DATA2F_M + 68 / 4, "NV4097_SET_VERTEX_DATA2F_M + 68" }, + { NV4097_SET_VERTEX_DATA2F_M + 72 / 4, "NV4097_SET_VERTEX_DATA2F_M + 72" }, + { NV4097_SET_VERTEX_DATA2F_M + 76 / 4, "NV4097_SET_VERTEX_DATA2F_M + 76" }, + { NV4097_SET_VERTEX_DATA2F_M + 80 / 4, "NV4097_SET_VERTEX_DATA2F_M + 80" }, + { NV4097_SET_VERTEX_DATA2F_M + 84 / 4, "NV4097_SET_VERTEX_DATA2F_M + 84" }, + { NV4097_SET_VERTEX_DATA2F_M + 88 / 4, "NV4097_SET_VERTEX_DATA2F_M + 88" }, + { NV4097_SET_VERTEX_DATA2F_M + 92 / 4, "NV4097_SET_VERTEX_DATA2F_M + 92" }, + { NV4097_SET_VERTEX_DATA2F_M + 96 / 4, "NV4097_SET_VERTEX_DATA2F_M + 96" }, + { NV4097_SET_VERTEX_DATA2F_M + 100 / 4, "NV4097_SET_VERTEX_DATA2F_M + 100" }, + { NV4097_SET_VERTEX_DATA2F_M + 104 / 4, "NV4097_SET_VERTEX_DATA2F_M + 104" }, + { NV4097_SET_VERTEX_DATA2F_M + 108 / 4, "NV4097_SET_VERTEX_DATA2F_M + 108" }, + { NV4097_SET_VERTEX_DATA2F_M + 112 / 4, "NV4097_SET_VERTEX_DATA2F_M + 112" }, + { NV4097_SET_VERTEX_DATA2F_M + 116 / 4, "NV4097_SET_VERTEX_DATA2F_M + 116" }, + { NV4097_SET_VERTEX_DATA2F_M + 120 / 4, "NV4097_SET_VERTEX_DATA2F_M + 120" }, + { NV4097_SET_VERTEX_DATA2F_M + 124 / 4, "NV4097_SET_VERTEX_DATA2F_M + 124" }, + { NV4097_SET_VERTEX_DATA2S_M, "NV4097_SET_VERTEX_DATA2S_M" }, + { NV4097_SET_VERTEX_DATA2S_M + 4 / 4, "NV4097_SET_VERTEX_DATA2S_M + 4" }, + { NV4097_SET_VERTEX_DATA2S_M + 8 / 4, "NV4097_SET_VERTEX_DATA2S_M + 8" }, + { NV4097_SET_VERTEX_DATA2S_M + 12 / 4, "NV4097_SET_VERTEX_DATA2S_M + 12" }, + { NV4097_SET_VERTEX_DATA2S_M + 16 / 4, "NV4097_SET_VERTEX_DATA2S_M + 16" }, + { NV4097_SET_VERTEX_DATA2S_M + 20 / 4, "NV4097_SET_VERTEX_DATA2S_M + 20" }, + { NV4097_SET_VERTEX_DATA2S_M + 24 / 4, "NV4097_SET_VERTEX_DATA2S_M + 24" }, + { NV4097_SET_VERTEX_DATA2S_M + 28 / 4, "NV4097_SET_VERTEX_DATA2S_M + 28" }, + { NV4097_SET_VERTEX_DATA2S_M + 32 / 4, "NV4097_SET_VERTEX_DATA2S_M + 32" }, + { NV4097_SET_VERTEX_DATA2S_M + 36 / 4, "NV4097_SET_VERTEX_DATA2S_M + 36" }, + { NV4097_SET_VERTEX_DATA2S_M + 40 / 4, "NV4097_SET_VERTEX_DATA2S_M + 40" }, + { NV4097_SET_VERTEX_DATA2S_M + 44 / 4, "NV4097_SET_VERTEX_DATA2S_M + 44" }, + { NV4097_SET_VERTEX_DATA2S_M + 48 / 4, "NV4097_SET_VERTEX_DATA2S_M + 48" }, + { NV4097_SET_VERTEX_DATA2S_M + 52 / 4, "NV4097_SET_VERTEX_DATA2S_M + 52" }, + { NV4097_SET_VERTEX_DATA2S_M + 56 / 4, "NV4097_SET_VERTEX_DATA2S_M + 56" }, + { NV4097_SET_VERTEX_DATA2S_M + 60 / 4, "NV4097_SET_VERTEX_DATA2S_M + 60" }, + { NV4097_SET_VERTEX_DATA4UB_M, "NV4097_SET_VERTEX_DATA4UB_M" }, + { NV4097_SET_VERTEX_DATA4UB_M + 4 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 4" }, + { NV4097_SET_VERTEX_DATA4UB_M + 8 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 8" }, + { NV4097_SET_VERTEX_DATA4UB_M + 12 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 12" }, + { NV4097_SET_VERTEX_DATA4UB_M + 16 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 16" }, + { NV4097_SET_VERTEX_DATA4UB_M + 20 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 20" }, + { NV4097_SET_VERTEX_DATA4UB_M + 24 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 24" }, + { NV4097_SET_VERTEX_DATA4UB_M + 28 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 28" }, + { NV4097_SET_VERTEX_DATA4UB_M + 32 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 32" }, + { NV4097_SET_VERTEX_DATA4UB_M + 36 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 36" }, + { NV4097_SET_VERTEX_DATA4UB_M + 40 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 40" }, + { NV4097_SET_VERTEX_DATA4UB_M + 44 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 44" }, + { NV4097_SET_VERTEX_DATA4UB_M + 48 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 48" }, + { NV4097_SET_VERTEX_DATA4UB_M + 52 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 52" }, + { NV4097_SET_VERTEX_DATA4UB_M + 56 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 56" }, + { NV4097_SET_VERTEX_DATA4UB_M + 60 / 4, "NV4097_SET_VERTEX_DATA4UB_M + 60" }, + { NV4097_SET_VERTEX_DATA4S_M, "NV4097_SET_VERTEX_DATA4S_M" }, + { NV4097_SET_VERTEX_DATA4S_M + 4 / 4, "NV4097_SET_VERTEX_DATA4S_M + 4" }, + { NV4097_SET_VERTEX_DATA4S_M + 8 / 4, "NV4097_SET_VERTEX_DATA4S_M + 8" }, + { NV4097_SET_VERTEX_DATA4S_M + 12 / 4, "NV4097_SET_VERTEX_DATA4S_M + 12" }, + { NV4097_SET_VERTEX_DATA4S_M + 16 / 4, "NV4097_SET_VERTEX_DATA4S_M + 16" }, + { NV4097_SET_VERTEX_DATA4S_M + 20 / 4, "NV4097_SET_VERTEX_DATA4S_M + 20" }, + { NV4097_SET_VERTEX_DATA4S_M + 24 / 4, "NV4097_SET_VERTEX_DATA4S_M + 24" }, + { NV4097_SET_VERTEX_DATA4S_M + 28 / 4, "NV4097_SET_VERTEX_DATA4S_M + 28" }, + { NV4097_SET_VERTEX_DATA4S_M + 32 / 4, "NV4097_SET_VERTEX_DATA4S_M + 32" }, + { NV4097_SET_VERTEX_DATA4S_M + 36 / 4, "NV4097_SET_VERTEX_DATA4S_M + 36" }, + { NV4097_SET_VERTEX_DATA4S_M + 40 / 4, "NV4097_SET_VERTEX_DATA4S_M + 40" }, + { NV4097_SET_VERTEX_DATA4S_M + 44 / 4, "NV4097_SET_VERTEX_DATA4S_M + 44" }, + { NV4097_SET_VERTEX_DATA4S_M + 48 / 4, "NV4097_SET_VERTEX_DATA4S_M + 48" }, + { NV4097_SET_VERTEX_DATA4S_M + 52 / 4, "NV4097_SET_VERTEX_DATA4S_M + 52" }, + { NV4097_SET_VERTEX_DATA4S_M + 56 / 4, "NV4097_SET_VERTEX_DATA4S_M + 56" }, + { NV4097_SET_VERTEX_DATA4S_M + 60 / 4, "NV4097_SET_VERTEX_DATA4S_M + 60" }, + { NV4097_SET_VERTEX_DATA4S_M + 64 / 4, "NV4097_SET_VERTEX_DATA4S_M + 64" }, + { NV4097_SET_VERTEX_DATA4S_M + 68 / 4, "NV4097_SET_VERTEX_DATA4S_M + 68" }, + { NV4097_SET_VERTEX_DATA4S_M + 72 / 4, "NV4097_SET_VERTEX_DATA4S_M + 72" }, + { NV4097_SET_VERTEX_DATA4S_M + 76 / 4, "NV4097_SET_VERTEX_DATA4S_M + 76" }, + { NV4097_SET_VERTEX_DATA4S_M + 80 / 4, "NV4097_SET_VERTEX_DATA4S_M + 80" }, + { NV4097_SET_VERTEX_DATA4S_M + 84 / 4, "NV4097_SET_VERTEX_DATA4S_M + 84" }, + { NV4097_SET_VERTEX_DATA4S_M + 88 / 4, "NV4097_SET_VERTEX_DATA4S_M + 88" }, + { NV4097_SET_VERTEX_DATA4S_M + 92 / 4, "NV4097_SET_VERTEX_DATA4S_M + 92" }, + { NV4097_SET_VERTEX_DATA4S_M + 96 / 4, "NV4097_SET_VERTEX_DATA4S_M + 96" }, + { NV4097_SET_VERTEX_DATA4S_M + 100 / 4, "NV4097_SET_VERTEX_DATA4S_M + 100" }, + { NV4097_SET_VERTEX_DATA4S_M + 104 / 4, "NV4097_SET_VERTEX_DATA4S_M + 104" }, + { NV4097_SET_VERTEX_DATA4S_M + 108 / 4, "NV4097_SET_VERTEX_DATA4S_M + 108" }, + { NV4097_SET_VERTEX_DATA4S_M + 112 / 4, "NV4097_SET_VERTEX_DATA4S_M + 112" }, + { NV4097_SET_VERTEX_DATA4S_M + 116 / 4, "NV4097_SET_VERTEX_DATA4S_M + 116" }, + { NV4097_SET_VERTEX_DATA4S_M + 120 / 4, "NV4097_SET_VERTEX_DATA4S_M + 120" }, + { NV4097_SET_VERTEX_DATA4S_M + 124 / 4, "NV4097_SET_VERTEX_DATA4S_M + 124" }, + { NV4097_SET_TEXTURE_OFFSET, "NV4097_SET_TEXTURE_OFFSET" }, + { NV4097_SET_TEXTURE_FORMAT, "NV4097_SET_TEXTURE_FORMAT" }, + { NV4097_SET_TEXTURE_ADDRESS, "NV4097_SET_TEXTURE_ADDRESS" }, + { NV4097_SET_TEXTURE_CONTROL0, "NV4097_SET_TEXTURE_CONTROL0" }, + { NV4097_SET_TEXTURE_CONTROL1, "NV4097_SET_TEXTURE_CONTROL1" }, + { NV4097_SET_TEXTURE_FILTER, "NV4097_SET_TEXTURE_FILTER" }, + { NV4097_SET_TEXTURE_IMAGE_RECT, "NV4097_SET_TEXTURE_IMAGE_RECT" }, + { NV4097_SET_TEXTURE_BORDER_COLOR, "NV4097_SET_TEXTURE_BORDER_COLOR" }, + { NV4097_SET_TEXTURE_OFFSET + 0x20 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x20" }, + { NV4097_SET_TEXTURE_FORMAT + 0x20 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x20" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x20 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x20" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x20 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x20" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x20 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x20" }, + { NV4097_SET_TEXTURE_FILTER + 0x20 / 4, "NV4097_SET_TEXTURE_FILTER + 0x20" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x20 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x20" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x20 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x20" }, + { NV4097_SET_TEXTURE_OFFSET + 0x40 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x40" }, + { NV4097_SET_TEXTURE_FORMAT + 0x40 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x40" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x40 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x40" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x40 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x40" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x40 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x40" }, + { NV4097_SET_TEXTURE_FILTER + 0x40 / 4, "NV4097_SET_TEXTURE_FILTER + 0x40" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x40 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x40" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x40 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x40" }, + { NV4097_SET_TEXTURE_OFFSET + 0x60 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x60" }, + { NV4097_SET_TEXTURE_FORMAT + 0x60 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x60" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x60 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x60" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x60 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x60" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x60 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x60" }, + { NV4097_SET_TEXTURE_FILTER + 0x60 / 4, "NV4097_SET_TEXTURE_FILTER + 0x60" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x60 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x60" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x60 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x60" }, + { NV4097_SET_TEXTURE_OFFSET + 0x80 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x80" }, + { NV4097_SET_TEXTURE_FORMAT + 0x80 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x80" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x80 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x80" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x80 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x80" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x80 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x80" }, + { NV4097_SET_TEXTURE_FILTER + 0x80 / 4, "NV4097_SET_TEXTURE_FILTER + 0x80" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x80 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x80" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x80 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x80" }, + { NV4097_SET_TEXTURE_OFFSET + 0xa0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0xa0" }, + { NV4097_SET_TEXTURE_FORMAT + 0xa0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0xa0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0xa0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0xa0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0xa0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0xa0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0xa0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0xa0" }, + { NV4097_SET_TEXTURE_FILTER + 0xa0 / 4, "NV4097_SET_TEXTURE_FILTER + 0xa0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0xa0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0xa0" }, + { NV4097_SET_TEXTURE_OFFSET + 0xc0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0xc0" }, + { NV4097_SET_TEXTURE_FORMAT + 0xc0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0xc0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0xc0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0xc0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0xc0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0xc0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0xc0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0xc0" }, + { NV4097_SET_TEXTURE_FILTER + 0xc0 / 4, "NV4097_SET_TEXTURE_FILTER + 0xc0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0xc0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0xc0" }, + { NV4097_SET_TEXTURE_OFFSET + 0xe0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0xe0" }, + { NV4097_SET_TEXTURE_FORMAT + 0xe0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0xe0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0xe0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0xe0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0xe0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0xe0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0xe0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0xe0" }, + { NV4097_SET_TEXTURE_FILTER + 0xe0 / 4, "NV4097_SET_TEXTURE_FILTER + 0xe0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0xe0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0xe0" }, + { NV4097_SET_TEXTURE_OFFSET + 0x100 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x100" }, + { NV4097_SET_TEXTURE_FORMAT + 0x100 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x100" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x100 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x100" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x100 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x100" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x100 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x100" }, + { NV4097_SET_TEXTURE_FILTER + 0x100 / 4, "NV4097_SET_TEXTURE_FILTER + 0x100" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x100 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x100" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x100 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x100" }, + { NV4097_SET_TEXTURE_OFFSET + 0x120 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x120" }, + { NV4097_SET_TEXTURE_FORMAT + 0x120 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x120" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x120 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x120" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x120 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x120" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x120 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x120" }, + { NV4097_SET_TEXTURE_FILTER + 0x120 / 4, "NV4097_SET_TEXTURE_FILTER + 0x120" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x120 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x120" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x120 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x120" }, + { NV4097_SET_TEXTURE_OFFSET + 0x140 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x140" }, + { NV4097_SET_TEXTURE_FORMAT + 0x140 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x140" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x140 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x140" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x140 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x140" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x140 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x140" }, + { NV4097_SET_TEXTURE_FILTER + 0x140 / 4, "NV4097_SET_TEXTURE_FILTER + 0x140" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x140 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x140" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x140 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x140" }, + { NV4097_SET_TEXTURE_OFFSET + 0x160 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x160" }, + { NV4097_SET_TEXTURE_FORMAT + 0x160 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x160" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x160 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x160" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x160 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x160" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x160 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x160" }, + { NV4097_SET_TEXTURE_FILTER + 0x160 / 4, "NV4097_SET_TEXTURE_FILTER + 0x160" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x160 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x160" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x160 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x160" }, + { NV4097_SET_TEXTURE_OFFSET + 0x180 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x180" }, + { NV4097_SET_TEXTURE_FORMAT + 0x180 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x180" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x180 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x180" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x180 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x180" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x180 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x180" }, + { NV4097_SET_TEXTURE_FILTER + 0x180 / 4, "NV4097_SET_TEXTURE_FILTER + 0x180" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x180 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x180" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x180 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x180" }, + { NV4097_SET_TEXTURE_OFFSET + 0x1a0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x1a0" }, + { NV4097_SET_TEXTURE_FORMAT + 0x1a0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x1a0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x1a0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x1a0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x1a0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x1a0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x1a0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x1a0" }, + { NV4097_SET_TEXTURE_FILTER + 0x1a0 / 4, "NV4097_SET_TEXTURE_FILTER + 0x1a0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1a0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1a0" }, + { NV4097_SET_TEXTURE_OFFSET + 0x1c0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x1c0" }, + { NV4097_SET_TEXTURE_FORMAT + 0x1c0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x1c0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x1c0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x1c0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x1c0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x1c0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x1c0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x1c0" }, + { NV4097_SET_TEXTURE_FILTER + 0x1c0 / 4, "NV4097_SET_TEXTURE_FILTER + 0x1c0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1c0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1c0" }, + { NV4097_SET_TEXTURE_OFFSET + 0x1e0 / 4, "NV4097_SET_TEXTURE_OFFSET + 0x1e0" }, + { NV4097_SET_TEXTURE_FORMAT + 0x1e0 / 4, "NV4097_SET_TEXTURE_FORMAT + 0x1e0" }, + { NV4097_SET_TEXTURE_ADDRESS + 0x1e0 / 4, "NV4097_SET_TEXTURE_ADDRESS + 0x1e0" }, + { NV4097_SET_TEXTURE_CONTROL0 + 0x1e0 / 4, "NV4097_SET_TEXTURE_CONTROL0 + 0x1e0" }, + { NV4097_SET_TEXTURE_CONTROL1 + 0x1e0 / 4, "NV4097_SET_TEXTURE_CONTROL1 + 0x1e0" }, + { NV4097_SET_TEXTURE_FILTER + 0x1e0 / 4, "NV4097_SET_TEXTURE_FILTER + 0x1e0" }, + { NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0 / 4, "NV4097_SET_TEXTURE_IMAGE_RECT + 0x1e0" }, + { NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0 / 4, "NV4097_SET_TEXTURE_BORDER_COLOR + 0x1e0" }, + { NV4097_SET_VERTEX_DATA4F_M, "NV4097_SET_VERTEX_DATA4F_M" }, + { NV4097_SET_VERTEX_DATA4F_M + 4 / 4, "NV4097_SET_VERTEX_DATA4F_M + 4" }, + { NV4097_SET_VERTEX_DATA4F_M + 8 / 4, "NV4097_SET_VERTEX_DATA4F_M + 8" }, + { NV4097_SET_VERTEX_DATA4F_M + 12 / 4, "NV4097_SET_VERTEX_DATA4F_M + 12" }, + { NV4097_SET_VERTEX_DATA4F_M + 16 / 4, "NV4097_SET_VERTEX_DATA4F_M + 16" }, + { NV4097_SET_VERTEX_DATA4F_M + 20 / 4, "NV4097_SET_VERTEX_DATA4F_M + 20" }, + { NV4097_SET_VERTEX_DATA4F_M + 24 / 4, "NV4097_SET_VERTEX_DATA4F_M + 24" }, + { NV4097_SET_VERTEX_DATA4F_M + 28 / 4, "NV4097_SET_VERTEX_DATA4F_M + 28" }, + { NV4097_SET_VERTEX_DATA4F_M + 32 / 4, "NV4097_SET_VERTEX_DATA4F_M + 32" }, + { NV4097_SET_VERTEX_DATA4F_M + 36 / 4, "NV4097_SET_VERTEX_DATA4F_M + 36" }, + { NV4097_SET_VERTEX_DATA4F_M + 40 / 4, "NV4097_SET_VERTEX_DATA4F_M + 40" }, + { NV4097_SET_VERTEX_DATA4F_M + 44 / 4, "NV4097_SET_VERTEX_DATA4F_M + 44" }, + { NV4097_SET_VERTEX_DATA4F_M + 48 / 4, "NV4097_SET_VERTEX_DATA4F_M + 48" }, + { NV4097_SET_VERTEX_DATA4F_M + 52 / 4, "NV4097_SET_VERTEX_DATA4F_M + 52" }, + { NV4097_SET_VERTEX_DATA4F_M + 56 / 4, "NV4097_SET_VERTEX_DATA4F_M + 56" }, + { NV4097_SET_VERTEX_DATA4F_M + 60 / 4, "NV4097_SET_VERTEX_DATA4F_M + 60" }, + { NV4097_SET_VERTEX_DATA4F_M + 64 / 4, "NV4097_SET_VERTEX_DATA4F_M + 64" }, + { NV4097_SET_VERTEX_DATA4F_M + 68 / 4, "NV4097_SET_VERTEX_DATA4F_M + 68" }, + { NV4097_SET_VERTEX_DATA4F_M + 72 / 4, "NV4097_SET_VERTEX_DATA4F_M + 72" }, + { NV4097_SET_VERTEX_DATA4F_M + 76 / 4, "NV4097_SET_VERTEX_DATA4F_M + 76" }, + { NV4097_SET_VERTEX_DATA4F_M + 80 / 4, "NV4097_SET_VERTEX_DATA4F_M + 80" }, + { NV4097_SET_VERTEX_DATA4F_M + 84 / 4, "NV4097_SET_VERTEX_DATA4F_M + 84" }, + { NV4097_SET_VERTEX_DATA4F_M + 88 / 4, "NV4097_SET_VERTEX_DATA4F_M + 88" }, + { NV4097_SET_VERTEX_DATA4F_M + 92 / 4, "NV4097_SET_VERTEX_DATA4F_M + 92" }, + { NV4097_SET_VERTEX_DATA4F_M + 96 / 4, "NV4097_SET_VERTEX_DATA4F_M + 96" }, + { NV4097_SET_VERTEX_DATA4F_M + 100 / 4, "NV4097_SET_VERTEX_DATA4F_M + 100" }, + { NV4097_SET_VERTEX_DATA4F_M + 104 / 4, "NV4097_SET_VERTEX_DATA4F_M + 104" }, + { NV4097_SET_VERTEX_DATA4F_M + 108 / 4, "NV4097_SET_VERTEX_DATA4F_M + 108" }, + { NV4097_SET_VERTEX_DATA4F_M + 112 / 4, "NV4097_SET_VERTEX_DATA4F_M + 112" }, + { NV4097_SET_VERTEX_DATA4F_M + 116 / 4, "NV4097_SET_VERTEX_DATA4F_M + 116" }, + { NV4097_SET_VERTEX_DATA4F_M + 120 / 4, "NV4097_SET_VERTEX_DATA4F_M + 120" }, + { NV4097_SET_VERTEX_DATA4F_M + 124 / 4, "NV4097_SET_VERTEX_DATA4F_M + 124" }, + { NV4097_SET_VERTEX_DATA4F_M + 128 / 4, "NV4097_SET_VERTEX_DATA4F_M + 128" }, + { NV4097_SET_VERTEX_DATA4F_M + 132 / 4, "NV4097_SET_VERTEX_DATA4F_M + 132" }, + { NV4097_SET_VERTEX_DATA4F_M + 136 / 4, "NV4097_SET_VERTEX_DATA4F_M + 136" }, + { NV4097_SET_VERTEX_DATA4F_M + 140 / 4, "NV4097_SET_VERTEX_DATA4F_M + 140" }, + { NV4097_SET_VERTEX_DATA4F_M + 144 / 4, "NV4097_SET_VERTEX_DATA4F_M + 144" }, + { NV4097_SET_VERTEX_DATA4F_M + 148 / 4, "NV4097_SET_VERTEX_DATA4F_M + 148" }, + { NV4097_SET_VERTEX_DATA4F_M + 152 / 4, "NV4097_SET_VERTEX_DATA4F_M + 152" }, + { NV4097_SET_VERTEX_DATA4F_M + 156 / 4, "NV4097_SET_VERTEX_DATA4F_M + 156" }, + { NV4097_SET_VERTEX_DATA4F_M + 160 / 4, "NV4097_SET_VERTEX_DATA4F_M + 160" }, + { NV4097_SET_VERTEX_DATA4F_M + 164 / 4, "NV4097_SET_VERTEX_DATA4F_M + 164" }, + { NV4097_SET_VERTEX_DATA4F_M + 168 / 4, "NV4097_SET_VERTEX_DATA4F_M + 168" }, + { NV4097_SET_VERTEX_DATA4F_M + 172 / 4, "NV4097_SET_VERTEX_DATA4F_M + 172" }, + { NV4097_SET_VERTEX_DATA4F_M + 176 / 4, "NV4097_SET_VERTEX_DATA4F_M + 176" }, + { NV4097_SET_VERTEX_DATA4F_M + 180 / 4, "NV4097_SET_VERTEX_DATA4F_M + 180" }, + { NV4097_SET_VERTEX_DATA4F_M + 184 / 4, "NV4097_SET_VERTEX_DATA4F_M + 184" }, + { NV4097_SET_VERTEX_DATA4F_M + 188 / 4, "NV4097_SET_VERTEX_DATA4F_M + 188" }, + { NV4097_SET_VERTEX_DATA4F_M + 192 / 4, "NV4097_SET_VERTEX_DATA4F_M + 192" }, + { NV4097_SET_VERTEX_DATA4F_M + 196 / 4, "NV4097_SET_VERTEX_DATA4F_M + 196" }, + { NV4097_SET_VERTEX_DATA4F_M + 200 / 4, "NV4097_SET_VERTEX_DATA4F_M + 200" }, + { NV4097_SET_VERTEX_DATA4F_M + 204 / 4, "NV4097_SET_VERTEX_DATA4F_M + 204" }, + { NV4097_SET_VERTEX_DATA4F_M + 208 / 4, "NV4097_SET_VERTEX_DATA4F_M + 208" }, + { NV4097_SET_VERTEX_DATA4F_M + 212 / 4, "NV4097_SET_VERTEX_DATA4F_M + 212" }, + { NV4097_SET_VERTEX_DATA4F_M + 216 / 4, "NV4097_SET_VERTEX_DATA4F_M + 216" }, + { NV4097_SET_VERTEX_DATA4F_M + 220 / 4, "NV4097_SET_VERTEX_DATA4F_M + 220" }, + { NV4097_SET_VERTEX_DATA4F_M + 224 / 4, "NV4097_SET_VERTEX_DATA4F_M + 224" }, + { NV4097_SET_VERTEX_DATA4F_M + 228 / 4, "NV4097_SET_VERTEX_DATA4F_M + 228" }, + { NV4097_SET_VERTEX_DATA4F_M + 232 / 4, "NV4097_SET_VERTEX_DATA4F_M + 232" }, + { NV4097_SET_VERTEX_DATA4F_M + 236 / 4, "NV4097_SET_VERTEX_DATA4F_M + 236" }, + { NV4097_SET_VERTEX_DATA4F_M + 240 / 4, "NV4097_SET_VERTEX_DATA4F_M + 240" }, + { NV4097_SET_VERTEX_DATA4F_M + 244 / 4, "NV4097_SET_VERTEX_DATA4F_M + 244" }, + { NV4097_SET_VERTEX_DATA4F_M + 248 / 4, "NV4097_SET_VERTEX_DATA4F_M + 248" }, + { NV4097_SET_VERTEX_DATA4F_M + 252 / 4, "NV4097_SET_VERTEX_DATA4F_M + 252" }, + { NV4097_SET_SHADER_CONTROL, "NV4097_SET_SHADER_CONTROL" }, + { NV4097_SET_SEMAPHORE_OFFSET, "NV4097_SET_SEMAPHORE_OFFSET" }, + { NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE, "NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE" }, + { NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, "NV4097_TEXTURE_READ_SEMAPHORE_RELEASE" }, + { NV4097_SET_ZMIN_MAX_CONTROL, "NV4097_SET_ZMIN_MAX_CONTROL" }, + { NV4097_SET_ANTI_ALIASING_CONTROL, "NV4097_SET_ANTI_ALIASING_CONTROL" }, + { NV4097_SET_ZCULL_EN, "NV4097_SET_ZCULL_EN" }, + { NV4097_SET_SHADER_WINDOW, "NV4097_SET_SHADER_WINDOW" }, + { NV4097_SET_ZSTENCIL_CLEAR_VALUE, "NV4097_SET_ZSTENCIL_CLEAR_VALUE" }, + { NV4097_SET_COLOR_CLEAR_VALUE, "NV4097_SET_COLOR_CLEAR_VALUE" }, + { NV4097_CLEAR_SURFACE, "NV4097_CLEAR_SURFACE" }, + { NV4097_SET_RESTART_INDEX_ENABLE, "NV4097_SET_RESTART_INDEX_ENABLE" }, + { NV4097_SET_RESTART_INDEX, "NV4097_SET_RESTART_INDEX" }, + { NV4097_SET_LINE_STIPPLE, "NV4097_SET_LINE_STIPPLE" }, + { NV4097_SET_LINE_STIPPLE_PATTERN, "NV4097_SET_LINE_STIPPLE_PATTERN" }, + { NV4097_SET_VERTEX_DATA1F_M, "NV4097_SET_VERTEX_DATA1F_M" }, + { NV4097_SET_VERTEX_DATA1F_M + 4 / 4, "NV4097_SET_VERTEX_DATA1F_M + 4" }, + { NV4097_SET_VERTEX_DATA1F_M + 8 / 4, "NV4097_SET_VERTEX_DATA1F_M + 8" }, + { NV4097_SET_VERTEX_DATA1F_M + 12 / 4, "NV4097_SET_VERTEX_DATA1F_M + 12" }, + { NV4097_SET_VERTEX_DATA1F_M + 16 / 4, "NV4097_SET_VERTEX_DATA1F_M + 16" }, + { NV4097_SET_VERTEX_DATA1F_M + 20 / 4, "NV4097_SET_VERTEX_DATA1F_M + 20" }, + { NV4097_SET_VERTEX_DATA1F_M + 24 / 4, "NV4097_SET_VERTEX_DATA1F_M + 24" }, + { NV4097_SET_VERTEX_DATA1F_M + 28 / 4, "NV4097_SET_VERTEX_DATA1F_M + 28" }, + { NV4097_SET_VERTEX_DATA1F_M + 32 / 4, "NV4097_SET_VERTEX_DATA1F_M + 32" }, + { NV4097_SET_VERTEX_DATA1F_M + 36 / 4, "NV4097_SET_VERTEX_DATA1F_M + 36" }, + { NV4097_SET_VERTEX_DATA1F_M + 40 / 4, "NV4097_SET_VERTEX_DATA1F_M + 40" }, + { NV4097_SET_VERTEX_DATA1F_M + 44 / 4, "NV4097_SET_VERTEX_DATA1F_M + 44" }, + { NV4097_SET_VERTEX_DATA1F_M + 48 / 4, "NV4097_SET_VERTEX_DATA1F_M + 48" }, + { NV4097_SET_VERTEX_DATA1F_M + 52 / 4, "NV4097_SET_VERTEX_DATA1F_M + 52" }, + { NV4097_SET_VERTEX_DATA1F_M + 56 / 4, "NV4097_SET_VERTEX_DATA1F_M + 56" }, + { NV4097_SET_VERTEX_DATA1F_M + 60 / 4, "NV4097_SET_VERTEX_DATA1F_M + 60" }, + { NV4097_SET_RENDER_ENABLE, "NV4097_SET_RENDER_ENABLE" }, + { NV4097_SET_TRANSFORM_PROGRAM_LOAD, "NV4097_SET_TRANSFORM_PROGRAM_LOAD" }, + { NV4097_SET_TRANSFORM_PROGRAM_START, "NV4097_SET_TRANSFORM_PROGRAM_START" }, + { NV4097_SET_ZCULL_CONTROL0, "NV4097_SET_ZCULL_CONTROL0" }, + { NV4097_SET_ZCULL_CONTROL1, "NV4097_SET_ZCULL_CONTROL1" }, + { NV4097_SET_SCULL_CONTROL, "NV4097_SET_SCULL_CONTROL" }, + { NV4097_SET_POINT_SIZE, "NV4097_SET_POINT_SIZE" }, + { NV4097_SET_POINT_PARAMS_ENABLE, "NV4097_SET_POINT_PARAMS_ENABLE" }, + { NV4097_SET_POINT_SPRITE_CONTROL, "NV4097_SET_POINT_SPRITE_CONTROL" }, + { NV4097_SET_TRANSFORM_TIMEOUT, "NV4097_SET_TRANSFORM_TIMEOUT" }, + { NV4097_SET_TRANSFORM_CONSTANT_LOAD, "NV4097_SET_TRANSFORM_CONSTANT_LOAD" }, + { NV4097_SET_FREQUENCY_DIVIDER_OPERATION, "NV4097_SET_FREQUENCY_DIVIDER_OPERATION" }, + { NV4097_SET_ATTRIB_COLOR, "NV4097_SET_ATTRIB_COLOR" }, + { NV4097_SET_ATTRIB_TEX_COORD, "NV4097_SET_ATTRIB_TEX_COORD" }, + { NV4097_SET_ATTRIB_TEX_COORD_EX, "NV4097_SET_ATTRIB_TEX_COORD_EX" }, + { NV4097_SET_ATTRIB_UCLIP0, "NV4097_SET_ATTRIB_UCLIP0" }, + { NV4097_SET_ATTRIB_UCLIP1, "NV4097_SET_ATTRIB_UCLIP1" }, + { NV4097_INVALIDATE_L2, "NV4097_INVALIDATE_L2" }, + { NV4097_SET_REDUCE_DST_COLOR, "NV4097_SET_REDUCE_DST_COLOR" }, + { NV4097_SET_NO_PARANOID_TEXTURE_FETCHES, "NV4097_SET_NO_PARANOID_TEXTURE_FETCHES" }, + { NV4097_SET_SHADER_PACKER, "NV4097_SET_SHADER_PACKER" }, + { NV4097_SET_VERTEX_ATTRIB_INPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_INPUT_MASK" }, + { NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, "NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK" }, + { NV4097_SET_TRANSFORM_BRANCH_BITS, "NV4097_SET_TRANSFORM_BRANCH_BITS" } + }; + + auto found = methods.find(id); + if (found != methods.end()) + { + return "CELL_GCM_" + found->second; + } + + return fmt::format("unknown/illegal method [0x%08x]", id); + } +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 5f6696c76e..861e82e7a1 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -28,7 +28,7 @@ std::string GLFragmentDecompilerThread::compareFunction(COMPARE f, const std::st void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS) { - OS << "#version 420" << std::endl; + OS << "#version 140" << std::endl; } void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS) @@ -110,7 +110,7 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) OS << " " << table[i].first << " = " << table[i].second << ";" << std::endl; } - OS << "};" << std::endl; + OS << "}" << std::endl; } void GLFragmentDecompilerThread::Task() diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index a1fe5ad58e..3e1b7271f0 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -6,54 +6,21 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "GLGSRender.h" -#include "../Common/TextureUtils.h" -#define CMD_DEBUG 0 #define DUMP_VERTEX_DATA 0 -#if CMD_DEBUG -#define CMD_LOG(...) LOG_NOTICE(RSX, __VA_ARGS__) -#else -#define CMD_LOG(...) -#endif - -GLuint g_flip_tex, g_depth_tex, g_pbo[6]; -int last_width = 0, last_height = 0, last_depth_format = 0; - -GLenum g_last_gl_error = GL_NO_ERROR; -void printGlError(GLenum err, const char* situation) -{ - if (err != GL_NO_ERROR) - { - LOG_ERROR(RSX, "%s: opengl error 0x%04x", situation, err); - Emu.Pause(); - } -} -void printGlError(GLenum err, const std::string& situation) -{ - printGlError(err, situation.c_str()); -} - -#if 0 -#define checkForGlError(x) /*x*/ -#endif - -void GLTexture::Create() +void GLTexture::create() { if (m_id) { - Delete(); + remove(); } - if (!m_id) - { - glGenTextures(1, &m_id); - checkForGlError("GLTexture::Init() -> glGenTextures"); - Bind(); - } + glGenTextures(1, &m_id); + bind(); } -int GLTexture::GetGlWrap(int wrap) +int GLTexture::gl_wrap(int wrap) { switch (wrap) { @@ -71,7 +38,7 @@ int GLTexture::GetGlWrap(int wrap) return GL_REPEAT; } -float GLTexture::GetMaxAniso(int aniso) +float GLTexture::max_aniso(int aniso) { switch (aniso) { @@ -89,21 +56,18 @@ float GLTexture::GetMaxAniso(int aniso) return 1.0f; } -void GLTexture::Init(rsx::texture& tex) +void GLTexture::init(rsx::texture& tex) { - if (tex.location() > 1) - { - return; - } + if (!m_id) + create(); - Bind(); + bind(); const u32 texaddr = rsx::get_address(tex.offset(), tex.location()); //LOG_WARNING(RSX, "texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", // m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod); //TODO: safe init - checkForGlError("GLTexture::Init() -> glBindTexture"); int format = tex.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN); @@ -119,7 +83,6 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_B8)"); static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; glRemap = swizzleMaskB8; @@ -129,21 +92,16 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_A1R5G5B5: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei"); // TODO: texture swizzling glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A1R5G5B5)"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_A1R5G5B5)"); break; } case CELL_GCM_TEXTURE_A4R4G4B4: { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A4R4G4B4)"); // We read it in as R4G4B4A4, so we need to remap each component. static const GLint swizzleMaskA4R4G4B4[] = { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; @@ -154,13 +112,8 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_R5G6B5: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(), tex.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G6B5)"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); break; } @@ -175,20 +128,19 @@ void GLTexture::Init(rsx::texture& tex) src = (u32*)pixels; dst = (u32*)unswizzledPixels; - log2width = log(tex.width()) / log(2); - log2height = log(tex.height()) / log(2); + log2width = (u32)log2(tex.width()); + log2height = (u32)log2(tex.height()); for (int i = 0; i < tex.height(); i++) { for (int j = 0; j < tex.width(); j++) { - dst[(i * tex.width()) + j] = src[rsx::linear_to_swizzle(j, i, 0, log2width, log2height, 0)]; + dst[(i*tex.height()) + j] = src[rsx::linear_to_swizzle(j, i, 0, log2width, log2height, 0)]; } } } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, is_swizzled ? unswizzledPixels : pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A8R8G8B8)"); break; } @@ -197,7 +149,6 @@ void GLTexture::Init(rsx::texture& tex) u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 8; glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT1)"); break; } @@ -206,7 +157,6 @@ void GLTexture::Init(rsx::texture& tex) u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT23)"); } break; @@ -215,14 +165,12 @@ void GLTexture::Init(rsx::texture& tex) u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16; glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT45)"); break; } case CELL_GCM_TEXTURE_G8B8: { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_G8B8)"); static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; glRemap = swizzleMaskG8B8; @@ -237,14 +185,13 @@ void GLTexture::Init(rsx::texture& tex) // TODO: Speed. for (u32 i = 0; i < numPixels; ++i) { u16 c = reinterpret_cast *>(pixels)[i]; - unswizzledPixels[i * 4 + 0] = Convert6To8((c >> 10) & 0x3F); - unswizzledPixels[i * 4 + 1] = Convert5To8((c >> 5) & 0x1F); - unswizzledPixels[i * 4 + 2] = Convert5To8((c >> 0) & 0x1F); + unswizzledPixels[i * 4 + 0] = convert_6_to_8((c >> 10) & 0x3F); + unswizzledPixels[i * 4 + 1] = convert_5_to_8((c >> 5) & 0x1F); + unswizzledPixels[i * 4 + 2] = convert_5_to_8((c >> 0) & 0x1F); unswizzledPixels[i * 4 + 3] = 255; } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R6G5B5)"); free(unswizzledPixels); break; @@ -253,41 +200,32 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8)"); break; } case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT)"); break; } case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16)"); break; } case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16_FLOAT)"); break; } case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X16)"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE }; glRemap = swizzleMaskX16; @@ -297,14 +235,8 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16)"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); - static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; glRemap = swizzleMaskX32_Y16_X16; break; @@ -313,40 +245,28 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_R5G5B5A1: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G5B5A1)"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); break; } case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_HALF_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); break; } case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT)"); break; } case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X32_FLOAT)"); static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE }; glRemap = swizzleMaskX32_FLOAT; @@ -356,24 +276,21 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_D1R5G5B5: { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); + // TODO: Texture swizzling glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D1R5G5B5)"); static const GLint swizzleMaskX32_D1R5G5B5[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; glRemap = swizzleMaskX32_D1R5G5B5; glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); break; } case CELL_GCM_TEXTURE_D8R8G8B8: // 8 bits of garbage and three unsigned 8-bit fixed-point numbers { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D8R8G8B8)"); static const GLint swizzleMaskX32_D8R8G8B8[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; glRemap = swizzleMaskX32_D8R8G8B8; @@ -384,13 +301,8 @@ void GLTexture::Init(rsx::texture& tex) case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values { glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_HALF_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; glRemap = swizzleMaskX32_Y16_X16_FLOAT; @@ -417,8 +329,6 @@ void GLTexture::Init(rsx::texture& tex) } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); - free(unswizzledPixels); break; } @@ -443,8 +353,6 @@ void GLTexture::Init(rsx::texture& tex) } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); - free(unswizzledPixels); break; } @@ -480,8 +388,6 @@ void GLTexture::Init(rsx::texture& tex) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[3]); } - checkForGlError("GLTexture::Init() -> remap"); - static const int gl_tex_zfunc[] = { GL_NEVER, @@ -494,21 +400,17 @@ void GLTexture::Init(rsx::texture& tex) GL_ALWAYS, }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.wrap_s())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.wrap_t())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.wrap_r())); - - checkForGlError("GLTexture::Init() -> wrap"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r())); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]); - checkForGlError("GLTexture::Init() -> compare"); - glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.bias()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8)); - checkForGlError("GLTexture::Init() -> lod"); + static const int gl_tex_min_filter[] = { @@ -531,15 +433,8 @@ void GLTexture::Init(rsx::texture& tex) }; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]); - - checkForGlError("GLTexture::Init() -> min filters"); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]); - - checkForGlError("GLTexture::Init() -> mag filters"); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GetMaxAniso(tex.max_aniso())); - - checkForGlError("GLTexture::Init() -> max anisotropy"); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso())); //Unbind(); @@ -549,7 +444,7 @@ void GLTexture::Init(rsx::texture& tex) } } -void GLTexture::Save(rsx::texture& tex, const std::string& name) +void GLTexture::save(rsx::texture& tex, const std::string& name) { if (!m_id || !tex.offset() || !tex.width() || !tex.height()) return; @@ -557,7 +452,7 @@ void GLTexture::Save(rsx::texture& tex, const std::string& name) u32* alldata = new u32[texPixelCount]; - Bind(); + bind(); switch (tex.format() & ~(0x20 | 0x40)) { @@ -574,7 +469,7 @@ void GLTexture::Save(rsx::texture& tex, const std::string& name) return; } - fs::file(name + ".raw", fom::write | fom::create | fom::trunc).write(alldata, texPixelCount * 4); + fs::file(name + ".raw", o_write | o_create | o_trunc).write(alldata, texPixelCount * 4); u8* data = new u8[texPixelCount * 3]; u8* alpha = new u8[texPixelCount]; @@ -599,7 +494,7 @@ void GLTexture::Save(rsx::texture& tex, const std::string& name) //free(alpha); } -void GLTexture::Save(rsx::texture& tex) +void GLTexture::save(rsx::texture& tex) { static const std::string& dir_path = "textures"; static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; @@ -608,20 +503,20 @@ void GLTexture::Save(rsx::texture& tex) u32 count = 0; while (fs::exists(fmt::format(file_fmt.c_str(), count))) count++; - Save(tex, fmt::format(file_fmt.c_str(), count)); + save(tex, fmt::format(file_fmt.c_str(), count)); } -void GLTexture::Bind() +void GLTexture::bind() { glBindTexture(GL_TEXTURE_2D, m_id); } -void GLTexture::Unbind() +void GLTexture::unbind() { glBindTexture(GL_TEXTURE_2D, 0); } -void GLTexture::Delete() +void GLTexture::remove() { if (m_id) { @@ -630,167 +525,18 @@ void GLTexture::Delete() } } -void PostDrawObj::Draw() +u32 GLTexture::id() const { - static bool s_is_initialized = false; - - if (!s_is_initialized) - { - s_is_initialized = true; - Initialize(); - } - else - { - m_program.Use(); - } + return m_id; } -void PostDrawObj::Initialize() -{ - InitializeShaders(); - m_fp.Compile(); - m_vp.Compile(); - m_program.Create(m_vp.id, m_fp.id); - m_program.Use(); - InitializeLocations(); -} - -void DrawCursorObj::Draw() -{ - checkForGlError("PostDrawObj : Unknown error."); - - PostDrawObj::Draw(); - checkForGlError("PostDrawObj::Draw"); - - if (!m_fbo.IsCreated()) - { - m_fbo.Create(); - checkForGlError("DrawCursorObj : m_fbo.Create"); - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); - - m_rbo.Create(); - checkForGlError("DrawCursorObj : m_rbo.Create"); - m_rbo.Bind(); - checkForGlError("DrawCursorObj : m_rbo.Bind"); - m_rbo.Storage(GL_RGBA, m_width, m_height); - checkForGlError("DrawCursorObj : m_rbo.Storage"); - - m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId()); - checkForGlError("DrawCursorObj : m_fbo.Renderbuffer"); - } - - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - checkForGlError("DrawCursorObj : glDrawBuffer"); - - m_program.Use(); - checkForGlError("DrawCursorObj : m_program.Use"); - - if (m_update_texture) - { - glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height); - checkForGlError("DrawCursorObj : glUniform2f"); - if (!m_tex_id) - { - glGenTextures(1, &m_tex_id); - checkForGlError("DrawCursorObj : glGenTextures"); - } - - glActiveTexture(GL_TEXTURE0); - checkForGlError("DrawCursorObj : glActiveTexture"); - glBindTexture(GL_TEXTURE_2D, m_tex_id); - checkForGlError("DrawCursorObj : glBindTexture"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels); - checkForGlError("DrawCursorObj : glTexImage2D"); - m_program.SetTex(0); - } - - if (m_update_pos) - { - glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f); - checkForGlError("DrawCursorObj : glUniform4f"); - } - - glDrawArrays(GL_QUADS, 0, 4); - checkForGlError("DrawCursorObj : glDrawArrays"); - - m_fbo.Bind(GL_READ_FRAMEBUFFER); - checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)"); - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); - checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)"); - GLfbo::Blit(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); - checkForGlError("DrawCursorObj : GLfbo::Blit"); - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); -} - -void DrawCursorObj::InitializeShaders() -{ - m_vp.shader = - "#version 420\n" - "\n" - "uniform vec4 in_pos;\n" - "uniform vec2 in_tc;\n" - "out vec2 tc;\n" - "\n" - "void main()\n" - "{\n" - " tc = in_tc;\n" - " gl_Position = in_pos;\n" - "}\n"; - - m_fp.shader = - "#version 420\n" - "\n" - "in vec2 tc;\n" - "layout (binding = 0) uniform sampler2D tex0;\n" - "layout (location = 0) out vec4 res;\n" - "\n" - "void main()\n" - "{\n" - " res = texture(tex0, tc);\n" - "}\n"; -} - -void DrawCursorObj::SetTexture(void* pixels, int width, int height) -{ - m_pixels = pixels; - m_width = width; - m_height = height; - - m_update_texture = true; -} - -void DrawCursorObj::SetPosition(float x, float y, float z) -{ - m_pos_x = x; - m_pos_y = y; - m_pos_z = z; - m_update_pos = true; -} - -void DrawCursorObj::InitializeLocations() -{ - //LOG_WARNING(RSX, "tex0 location = 0x%x", m_program.GetLocation("tex0")); -} - -GLGSRender::GLGSRender() - : GSRender(frame_type::OpenGL) - , m_fp_buf_num(-1) - , m_vp_buf_num(-1) - , m_context(nullptr) +GLGSRender::GLGSRender() : GSRender(frame_type::OpenGL) { } -GLGSRender::~GLGSRender() +u32 GLGSRender::enable(u32 condition, u32 cap) { -} - -void GLGSRender::Enable(bool enable, const u32 cap) -{ - if (enable) + if (condition) { glEnable(cap); } @@ -798,1146 +544,1274 @@ void GLGSRender::Enable(bool enable, const u32 cap) { glDisable(cap); } + + return condition; +} + +u32 GLGSRender::enable(u32 condition, u32 cap, u32 index) +{ + if (condition) + { + glEnablei(cap, index); + } + else + { + glDisablei(cap, index); + } + + return condition; } extern CellGcmContextData current_context; -void GLGSRender::EnableVertexData(bool indexed_draw) +void GLGSRender::begin() { - static u32 offset_list[rsx::limits::vertex_count]; - u32 cur_offset = 0; + rsx::thread::begin(); - const u32 data_offset = indexed_draw ? 0 : draw_array_first; - - for (u32 i = 0; i < rsx::limits::vertex_count; ++i) + if (!load_program()) { - if (0) + //no program - no drawing + return; + } + + init_buffers(); + + u32 color_mask = rsx::method_registers[NV4097_SET_COLOR_MASK]; + bool color_mask_b = color_mask & 0xff; + bool color_mask_g = (color_mask >> 8) & 0xff; + bool color_mask_r = (color_mask >> 16) & 0xff; + bool color_mask_a = (color_mask >> 24) & 0xff; + + __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); + __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); + __glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]); + + int viewport_x = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] & 0xffff); + int viewport_y = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] & 0xffff); + int viewport_w = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] >> 16); + int viewport_h = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] >> 16); + glViewport(viewport_x, viewport_y, viewport_w, viewport_h); + + //scissor test is always enabled + glEnable(GL_SCISSOR_TEST); + + u32 scissor_horizontal = rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL]; + u32 scissor_vertical = rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]; + u16 scissor_x = scissor_horizontal; + u16 scissor_w = scissor_horizontal >> 16; + u16 scissor_y = scissor_vertical; + u16 scissor_h = scissor_vertical >> 16; + + __glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h); + + if (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) + { + __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); + __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); + } + + if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT))) + { + __glcheck glDepthBoundsEXT((f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN], (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]); + } + + __glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]); + __glcheck enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER); + + if (__glcheck enable(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE], GL_ALPHA_TEST)) + { + //TODO: NV4097_SET_ALPHA_REF must be converted to f32 + //glcheck(glAlphaFunc(rsx::method_registers[NV4097_SET_ALPHA_FUNC], rsx::method_registers[NV4097_SET_ALPHA_REF])); + } + + if (__glcheck enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND)) + { + u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR]; + u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR]; + u16 sfactor_rgb = sfactor; + u16 sfactor_a = sfactor >> 16; + u16 dfactor_rgb = dfactor; + u16 dfactor_a = dfactor >> 16; + + __glcheck glBlendFuncSeparate(sfactor_rgb, dfactor_rgb, sfactor_a, dfactor_a); + + if (m_surface.color_format == CELL_GCM_SURFACE_F_W16Z16Y16X16) //TODO: check another color formats { - u32 data_format = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + i * 4]; - u16 frequency = data_format >> 16; - u8 stride = (data_format >> 8) & 0xff; - u8 size = (data_format >> 4) & 0xf; - u8 type = data_format & 0xf; + u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; + u32 blend_color2 = rsx::method_registers[NV4097_SET_BLEND_COLOR2]; - u32 type_size = 1; - switch (type) - { - case CELL_GCM_VERTEX_S1: type_size = 2; break; - case CELL_GCM_VERTEX_F: type_size = 4; break; - case CELL_GCM_VERTEX_SF: type_size = 2; break; - case CELL_GCM_VERTEX_UB: type_size = 1; break; - case CELL_GCM_VERTEX_S32K: type_size = 2; break; - case CELL_GCM_VERTEX_CMP: type_size = 4; break; - case CELL_GCM_VERTEX_UB256: type_size = 1; break; + u16 blend_color_r = blend_color; + u16 blend_color_g = blend_color >> 16; + u16 blend_color_b = blend_color2; + u16 blend_color_a = blend_color2 >> 16; - default: - LOG_ERROR(RSX, "RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type); - break; - } + __glcheck glBlendColor(blend_color_r / 65535.f, blend_color_g / 65535.f, blend_color_b / 65535.f, blend_color_a / 65535.f); + } + else + { + u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; + u8 blend_color_r = blend_color; + u8 blend_color_g = blend_color >> 8; + u8 blend_color_b = blend_color >> 16; + u8 blend_color_a = blend_color >> 24; - int item_size = size * type_size; + __glcheck glBlendColor(blend_color_r / 255.f, blend_color_g / 255.f, blend_color_b / 255.f, blend_color_a / 255.f); } - offset_list[i] = cur_offset; + u32 equation = rsx::method_registers[NV4097_SET_BLEND_EQUATION]; + u16 equation_rgb = equation; + u16 equation_a = equation >> 16; -/* if (!m_vertex_data[i].IsEnabled()) continue; - const size_t item_size = rsx::get_vertex_type_size(m_vertex_data[i].type) * m_vertex_data[i].size; - const size_t data_size = m_vertex_data[i].data.size() - data_offset * item_size; - const u32 pos = m_vdata.size(); - - cur_offset += data_size; - m_vdata.resize(m_vdata.size() + data_size); - memcpy(&m_vdata[pos], &m_vertex_data[i].data[data_offset * item_size], data_size);*/ + __glcheck glBlendEquationSeparate(equation_rgb, equation_a); } - - m_vao.Create(); - m_vao.Bind(); - checkForGlError("initializing vao"); - - m_vbo.Create(indexed_draw ? 2 : 1); - m_vbo.Bind(0); - m_vbo.SetData(m_vdata.data(), m_vdata.size()); - - if (indexed_draw) + + if (__glcheck enable(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE], GL_STENCIL_TEST)) { - m_vbo.Bind(GL_ELEMENT_ARRAY_BUFFER, 1); - m_vbo.SetData(GL_ELEMENT_ARRAY_BUFFER, m_indexed_array.m_data.data(), m_indexed_array.m_data.size()); + __glcheck glStencilFunc(rsx::method_registers[NV4097_SET_STENCIL_FUNC], rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF], + rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]); + __glcheck glStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL], rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL], + rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); + + if (__glcheck enable(rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE], GL_STENCIL_TEST_TWO_SIDE_EXT)) + { + __glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_MASK]); + __glcheck glStencilFuncSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC], + rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC_REF], rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC_MASK]); + __glcheck glStencilOpSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL], + rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL], rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]); + } } - checkForGlError("initializing vbo"); + __glcheck glShadeModel(rsx::method_registers[NV4097_SET_SHADE_MODE]); + + if (u32 blend_mrt = rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT]) + { + __glcheck enable(blend_mrt & 2, GL_BLEND, GL_COLOR_ATTACHMENT1); + __glcheck enable(blend_mrt & 4, GL_BLEND, GL_COLOR_ATTACHMENT2); + __glcheck enable(blend_mrt & 8, GL_BLEND, GL_COLOR_ATTACHMENT3); + } + + if (__glcheck enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_LOGIC_OP)) + { + __glcheck glLogicOp(rsx::method_registers[NV4097_SET_LOGIC_OP]); + } + + u32 line_width = rsx::method_registers[NV4097_SET_LINE_WIDTH]; + __glcheck glLineWidth((line_width >> 3) + (line_width & 7) / 8.f); + __glcheck enable(rsx::method_registers[NV4097_SET_LINE_SMOOTH_ENABLE], GL_LINE_SMOOTH); + + //TODO + //NV4097_SET_ANISO_SPREAD + + //TODO + /* + glcheck(glFogi(GL_FOG_MODE, rsx::method_registers[NV4097_SET_FOG_MODE])); + f32 fog_p0 = (f32&)rsx::method_registers[NV4097_SET_FOG_PARAMS + 0]; + f32 fog_p1 = (f32&)rsx::method_registers[NV4097_SET_FOG_PARAMS + 1]; + + f32 fog_start = (2 * fog_p0 - (fog_p0 - 2) / fog_p1) / (fog_p0 - 1); + f32 fog_end = (2 * fog_p0 - 1 / fog_p1) / (fog_p0 - 1); + + glFogf(GL_FOG_START, fog_start); + glFogf(GL_FOG_END, fog_end); + */ + //NV4097_SET_FOG_PARAMS + + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_POINT_ENABLE], GL_POLYGON_OFFSET_POINT); + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_LINE_ENABLE], GL_POLYGON_OFFSET_LINE); + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL); + + __glcheck glPolygonOffset((f32&)rsx::method_registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR], + (f32&)rsx::method_registers[NV4097_SET_POLYGON_OFFSET_BIAS]); + + //NV4097_SET_SPECULAR_ENABLE + //NV4097_SET_TWO_SIDE_LIGHT_EN + //NV4097_SET_FLAT_SHADE_OP + //NV4097_SET_EDGE_FLAG + + u32 clip_plane_control = rsx::method_registers[NV4097_SET_USER_CLIP_PLANE_CONTROL]; + u8 clip_plane_0 = clip_plane_control & 0xf; + u8 clip_plane_1 = (clip_plane_control >> 4) & 0xf; + u8 clip_plane_2 = (clip_plane_control >> 8) & 0xf; + u8 clip_plane_3 = (clip_plane_control >> 12) & 0xf; + u8 clip_plane_4 = (clip_plane_control >> 16) & 0xf; + u8 clip_plane_5 = (clip_plane_control >> 20) & 0xf; + + //TODO + if (__glcheck enable(clip_plane_0, GL_CLIP_DISTANCE0)) {} + if (__glcheck enable(clip_plane_1, GL_CLIP_DISTANCE1)) {} + if (__glcheck enable(clip_plane_2, GL_CLIP_DISTANCE2)) {} + if (__glcheck enable(clip_plane_3, GL_CLIP_DISTANCE3)) {} + if (__glcheck enable(clip_plane_4, GL_CLIP_DISTANCE4)) {} + if (__glcheck enable(clip_plane_5, GL_CLIP_DISTANCE5)) {} + + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL); + + if (__glcheck enable(rsx::method_registers[NV4097_SET_POLYGON_STIPPLE], GL_POLYGON_STIPPLE)) + { + __glcheck glPolygonStipple((GLubyte*)(rsx::method_registers + NV4097_SET_POLYGON_STIPPLE_PATTERN)); + } + + __glcheck glPolygonMode(GL_FRONT, rsx::method_registers[NV4097_SET_FRONT_POLYGON_MODE]); + __glcheck glPolygonMode(GL_BACK, rsx::method_registers[NV4097_SET_BACK_POLYGON_MODE]); + + if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE)) + { + __glcheck glCullFace(rsx::method_registers[NV4097_SET_CULL_FACE]); + __glcheck glFrontFace(rsx::method_registers[NV4097_SET_FRONT_FACE]); + } + + __glcheck enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH); + + //NV4097_SET_COLOR_KEY_COLOR + //NV4097_SET_SHADER_CONTROL + //NV4097_SET_ZMIN_MAX_CONTROL + //NV4097_SET_ANTI_ALIASING_CONTROL + //NV4097_SET_CLIP_ID_TEST_ENABLE + + if (__glcheck enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART)) + { + __glcheck glPrimitiveRestartIndex(rsx::method_registers[NV4097_SET_RESTART_INDEX]); + } + + if (__glcheck enable(rsx::method_registers[NV4097_SET_LINE_STIPPLE], GL_LINE_STIPPLE)) + { + u32 line_stipple_pattern = rsx::method_registers[NV4097_SET_LINE_STIPPLE_PATTERN]; + u16 factor = line_stipple_pattern; + u16 pattern = line_stipple_pattern >> 16; + __glcheck glLineStipple(factor, pattern); + } +} + +template +struct apply_attrib_t; + +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int location, const T* data) + { + program.attribs[location] = data[0]; + } +}; + +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int location, const T* data) + { + program.attribs[location] = color2_base{ data[0], data[1] }; + } +}; + +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int location, const T* data) + { + program.attribs[location] = color3_base{ data[0], data[1], data[2] }; + } +}; +template +struct apply_attrib_t +{ + static void func(gl::glsl::program& program, int location, const T* data) + { + program.attribs[location] = color4_base{ data[0], data[1], data[2], data[3] }; + } +}; + + +template +void apply_attrib_array(gl::glsl::program& program, int location, const std::vector& data) +{ + for (size_t offset = 0; offset < data.size(); offset += count * sizeof(T)) + { + apply_attrib_t::func(program, location, (T*)(data.data() + offset)); + } +} + +void GLGSRender::end() +{ + if (!draw_fbo || !vertex_draw_count) + { + rsx::thread::end(); + return; + } + + LOG_NOTICE(Log::RSX, "draw()"); + + draw_fbo.bind(); + m_program.use(); + + //setup textures + for (int i = 0; i < rsx::limits::textures_count; ++i) + { + if (!textures[i].enabled()) + continue; + + int location; + if (m_program.uniforms.has_location("tex" + std::to_string(i), &location)) + { + __glcheck m_gl_textures[i].init(textures[i]); + __glcheck m_program.uniforms.texture(location, i, gl::texture_view(gl::texture::target::texture2D, m_gl_textures[i].id())); + } + } + + //initialize vertex attributes + static const gl::buffer_pointer::type gl_types[] = + { + gl::buffer_pointer::type::f32, + + gl::buffer_pointer::type::s16, + gl::buffer_pointer::type::f32, + gl::buffer_pointer::type::f16, + gl::buffer_pointer::type::u8, + gl::buffer_pointer::type::s16, + gl::buffer_pointer::type::f32, // Needs conversion + gl::buffer_pointer::type::u8 + }; + + static const bool gl_normalized[] = + { + false, + + true, + false, + false, + true, + false, + true, + false + }; + + //merge all vertex arrays + std::vector vertex_arrays_data; + size_t vertex_arrays_offsets[rsx::limits::vertex_count]; #if DUMP_VERTEX_DATA - rFile dump("VertexDataArray.dump", rFile::write); + fs::file dump("VertexDataArray.dump", o_create | o_write); + Emu.Pause(); #endif - for (u32 i = 0; i < rsx::limits::vertex_count; ++i) + for (int index = 0; index < rsx::limits::vertex_count; ++index) { -// if (!m_vertex_data[i].IsEnabled()) continue; + size_t position = vertex_arrays_data.size(); + vertex_arrays_offsets[index] = position; + + if (vertex_arrays[index].empty()) + continue; + + size_t size = vertex_arrays[index].size(); + vertex_arrays_data.resize(position + size); + + memcpy(vertex_arrays_data.data() + position, vertex_arrays[index].data(), size); #if DUMP_VERTEX_DATA - dump.Write(wxString::Format("VertexData[%d]:\n", i)); - switch (m_vertex_data[i].type) + auto &vertex_info = vertex_arrays_info[index]; + dump.write(fmt::format("VertexData[%d]:\n", index)); + switch (vertex_info.type) { case CELL_GCM_VERTEX_S1: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 2) { - dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j])); - if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::format("%d\n", *(u16*)&vertex_arrays[index][j])); + if (!(((j + 2) / 2) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_F: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 4) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 4) { - dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j])); - if (!(((j + 4) / 4) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%.01f\n", *(float*)&vertex_arrays[index][j])); + if (!(((j + 4) / 4) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_SF: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 2) { - dump.Write(wxString::Format("%.01f\n", *(float*)&m_vertex_data[i].data[j])); - if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%.01f\n", *(float*)&vertex_arrays[index][j])); + if (!(((j + 2) / 2) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_UB: - for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j) + for (u32 j = 0; j < vertex_arrays[index].size(); ++j) { - dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j])); - if (!((j + 1) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%d\n", vertex_arrays[index][j])); + if (!((j + 1) % vertex_info.size)) dump.write("\n"); } break; case CELL_GCM_VERTEX_S32K: - for (u32 j = 0; j < m_vertex_data[i].data.size(); j += 2) + for (u32 j = 0; j < vertex_arrays[index].size(); j += 2) { - dump.Write(wxString::Format("%d\n", *(u16*)&m_vertex_data[i].data[j])); - if (!(((j + 2) / 2) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%d\n", *(u16*)&vertex_arrays[index][j])); + if (!(((j + 2) / 2) % vertex_info.size)) dump.write("\n"); } break; // case CELL_GCM_VERTEX_CMP: case CELL_GCM_VERTEX_UB256: - for (u32 j = 0; j < m_vertex_data[i].data.size(); ++j) + for (u32 j = 0; j < vertex_arrays[index].size(); ++j) { - dump.Write(wxString::Format("%d\n", m_vertex_data[i].data[j])); - if (!((j + 1) % m_vertex_data[i].size)) dump.Write("\n"); + dump.write(fmt::Format("%d\n", vertex_arrays[index][j])); + if (!((j + 1) % vertex_info.size)) dump.write("\n"); } break; - - default: - LOG_ERROR(HLE, "Bad cv type! %d", m_vertex_data[i].type); - return; } - dump.Write("\n"); + dump.write("\n"); #endif + } - static const u32 gl_types[] = - { - GL_SHORT, - GL_FLOAT, - GL_HALF_FLOAT, - GL_UNSIGNED_BYTE, - GL_SHORT, - GL_FLOAT, // Needs conversion - GL_UNSIGNED_BYTE, - }; + gl::vao vao; + vao.create(); - static const bool gl_normalized[] = - { - GL_TRUE, - GL_FALSE, - GL_FALSE, - GL_TRUE, - GL_FALSE, - GL_TRUE, - GL_FALSE, - }; + gl::buffer vbo; + vbo.create(vertex_arrays_data.size(), vertex_arrays_data.data()); -/* if (m_vertex_data[i].type < 1 || m_vertex_data[i].type > 7) + vao.array_buffer = vbo; + vao.bind(); + + for (int index = 0; index < rsx::limits::vertex_count; ++index) + { + auto &vertex_info = vertex_arrays_info[index]; + + if (!vertex_info.size) { - LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", m_vertex_data[i].type); + //disabled + continue; } - if (!m_vertex_data[i].addr) + if (vertex_info.type < 1 || vertex_info.type > 7) { - switch (m_vertex_data[i].type) - { - case CELL_GCM_VERTEX_S32K: - case CELL_GCM_VERTEX_S1: - switch(m_vertex_data[i].size) - { - case 1: glVertexAttrib1s(i, (GLshort&)m_vertex_data[i].data[0]); break; - case 2: glVertexAttrib2sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; - case 3: glVertexAttrib3sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; - case 4: glVertexAttrib4sv(i, (GLshort*)&m_vertex_data[i].data[0]); break; - } - break; + LOG_ERROR(RSX, "GLGSRender::EnableVertexData: Bad vertex data type (%d)!", vertex_info.type); + continue; + } - case CELL_GCM_VERTEX_F: - switch (m_vertex_data[i].size) - { - case 1: glVertexAttrib1f(i, (GLfloat&)m_vertex_data[i].data[0]); break; - case 2: glVertexAttrib2fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; - case 3: glVertexAttrib3fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; - case 4: glVertexAttrib4fv(i, (GLfloat*)&m_vertex_data[i].data[0]); break; - } - break; + static const std::string reg_table[] = + { + "in_pos", "in_weight", "in_normal", + "in_diff_color", "in_spec_color", + "in_fog", + "in_point_size", "in_7", + "in_tc0", "in_tc1", "in_tc2", "in_tc3", + "in_tc4", "in_tc5", "in_tc6", "in_tc7" + }; - case CELL_GCM_VERTEX_CMP: - case CELL_GCM_VERTEX_UB: - glVertexAttrib4ubv(i, (GLubyte*)&m_vertex_data[i].data[0]); - break; - } + int location = m_program.attribs.location(reg_table[index]); - checkForGlError("glVertexAttrib"); + if (vertex_info.array) + { + __glcheck m_program.attribs[location] = + (vao + vertex_arrays_offsets[index]) + .config(gl_types[vertex_info.type], vertex_info.size, gl_normalized[vertex_info.type]); } else { - u32 gltype = gl_types[m_vertex_data[i].type - 1]; - bool normalized = gl_normalized[m_vertex_data[i].type - 1]; + auto &vertex_data = vertex_arrays[index]; - glEnableVertexAttribArray(i); - checkForGlError("glEnableVertexAttribArray"); - glVertexAttribPointer(i, m_vertex_data[i].size, gltype, normalized, 0, reinterpret_cast(offset_list[i])); - checkForGlError("glVertexAttribPointer"); - }*/ + switch (vertex_info.type) + { + case CELL_GCM_VERTEX_F: + switch (vertex_info.size) + { + case 1: apply_attrib_array(m_program, location, vertex_data); break; + case 2: apply_attrib_array(m_program, location, vertex_data); break; + case 3: apply_attrib_array(m_program, location, vertex_data); break; + case 4: apply_attrib_array(m_program, location, vertex_data); break; + } + break; + + default: + LOG_ERROR(RSX, "bad non array vertex data format (type = %d, size = %d)", vertex_info.type, vertex_info.size); + break; + } + } } -} -void GLGSRender::DisableVertexData() -{ - m_vdata.clear(); - for (u32 i = 0; i < rsx::limits::vertex_count; ++i) + if (vertex_index_array.empty()) { -// if (!m_vertex_data[i].IsEnabled()) continue; - glDisableVertexAttribArray(i); - checkForGlError("glDisableVertexAttribArray"); + draw_fbo.draw_arrays(gl::draw_mode(draw_mode - 1), vertex_draw_count);\ } - m_vao.Unbind(); + else + { + gl::buffer index_buffer; + index_buffer.create(vertex_index_array.size(), vertex_index_array.data()); + vao.element_array_buffer = index_buffer; + + u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; + + __glcheck glDrawElements(draw_mode - 1, vertex_draw_count, + (indexed_type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT), nullptr); + } + + write_buffers(); + + rsx::thread::end(); } -void GLGSRender::InitVertexData() +void GLGSRender::oninit_thread() { - int l; - GLfloat scaleOffsetMat[16] = - { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + GSRender::oninit_thread(); -/* for (const RSXTransformConstant& c : m_transform_constants) - { - const std::string name = fmt::format("vc[%u]", c.id); - l = m_program.GetLocation(name); - checkForGlError("glGetUniformLocation " + name); + gl::init(); + LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_VERSION)); + LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION)); + LOG_NOTICE(Log::RSX, (const char*)glGetString(GL_VENDOR)); - glUniform4f(l, c.x, c.y, c.z, c.w); - checkForGlError("glUniform4f " + name + fmt::format(" %d [%f %f %f %f]", l, c.x, c.y, c.z, c.w)); - }*/ - - // Scale -/* scaleOffsetMat[0] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 0)] / (RSXThread::m_width / RSXThread::m_width_scale); - scaleOffsetMat[5] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 1)] / (RSXThread::m_height / RSXThread::m_height_scale); - scaleOffsetMat[10] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + (0x4 * 2)]; - - // Offset - scaleOffsetMat[3] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 0)] - (RSXThread::m_width / RSXThread::m_width_scale); - scaleOffsetMat[7] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 1)] - (RSXThread::m_height / RSXThread::m_height_scale); - scaleOffsetMat[11] = (GLfloat&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + (0x4 * 2)] - 1 / 2.0f; - - scaleOffsetMat[3] /= RSXThread::m_width / RSXThread::m_width_scale; - scaleOffsetMat[7] /= RSXThread::m_height / RSXThread::m_height_scale;*/ - - l = m_program.GetLocation("scaleOffsetMat"); - glUniformMatrix4fv(l, 1, false, scaleOffsetMat); - checkForGlError("glUniformMatrix4fv"); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); } -void GLGSRender::InitFragmentData() +void GLGSRender::onexit_thread() { -/* if (!m_cur_fragment_prog) + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + + //if (m_program) + // m_program.remove(); + + if (draw_fbo) + draw_fbo.remove(); + + for (auto &tex : m_draw_tex_color) + if (tex) tex.remove(); + + if (m_draw_tex_depth_stencil) + m_draw_tex_depth_stencil.remove(); + + if (m_flip_fbo) + m_flip_fbo.remove(); + + if (m_flip_tex_color) + m_flip_tex_color.remove(); +} + +void nv4097_clear_surface(u32 arg, GLGSRender* renderer) +{ + LOG_NOTICE(Log::RSX, "nv4097_clear_surface(0x%x)", arg); + + if ((arg & 0xf3) == 0) { - LOG_ERROR(RSX, "InitFragmentData: m_cur_shader_prog == NULL"); + //do nothing return; } - // Get constant from fragment program - const std::vector &fragmentOffset = m_prog_buffer.getFragmentConstantOffsetsCache(m_cur_fragment_prog); - for (size_t offsetInFP : fragmentOffset) + renderer->draw_fbo.bind(); + glEnable(GL_SCISSOR_TEST); + + /* + u16 clear_x = rsx::method_registers[NV4097_SET_CLEAR_RECT_HORIZONTAL]; + u16 clear_y = rsx::method_registers[NV4097_SET_CLEAR_RECT_VERTICAL]; + u16 clear_w = rsx::method_registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] >> 16; + u16 clear_h = rsx::method_registers[NV4097_SET_CLEAR_RECT_VERTICAL] >> 16; + glScissor(clear_x, clear_y, clear_w, clear_h); + */ + + u32 scissor_horizontal = rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL]; + u32 scissor_vertical = rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]; + u16 scissor_x = scissor_horizontal; + u16 scissor_w = scissor_horizontal >> 16; + u16 scissor_y = scissor_vertical; + u16 scissor_h = scissor_vertical >> 16; + + glScissor(scissor_x, scissor_y, scissor_w, scissor_h); + + GLbitfield mask = 0; + + if (arg & 0x1) { - auto data = vm::ps3::ptr::make(m_cur_fragment_prog->addr + (u32)offsetInFP); + u32 surface_depth_format = (rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7; + u32 max_depth_value = surface_depth_format == CELL_GCM_SURFACE_Z16 ? 0x0000ffff : 0x00ffffff; + + u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; + + glDepthMask(GL_TRUE); + glClearDepth(double(clear_depth) / max_depth_value); + mask |= GLenum(gl::buffers::depth); + } + + if (arg & 0x2) + { + u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff; + + __glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]); + glClearStencil(clear_stencil); + + mask |= GLenum(gl::buffers::stencil); + } + + if (arg & 0xf0) + { + u32 clear_color = rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]; + u8 clear_a = clear_color >> 24; + u8 clear_r = clear_color >> 16; + u8 clear_g = clear_color >> 8; + u8 clear_b = clear_color; + + glColorMask(((arg & 0x20) ? 1 : 0), ((arg & 0x40) ? 1 : 0), ((arg & 0x80) ? 1 : 0), ((arg & 0x10) ? 1 : 0)); + glClearColor(clear_r / 255.f, clear_g / 255.f, clear_b / 255.f, clear_a / 255.f); + + mask |= GLenum(gl::buffers::color); + } + + renderer->clear_surface_buffers = (gl::buffers)mask; + renderer->draw_fbo.clear((gl::buffers)mask); +} + +using rsx_method_impl_t = void(*)(u32, GLGSRender*); + +static const std::unordered_map g_gl_method_tbl = +{ + { NV4097_CLEAR_SURFACE, nv4097_clear_surface }, +}; + +bool GLGSRender::domethod(u32 cmd, u32 arg) +{ + auto found = g_gl_method_tbl.find(cmd); + + if (found == g_gl_method_tbl.end()) + { + return false; + } + + found->second(arg, this); + return true; +} + +bool GLGSRender::load_program() +{ +#if 1 + RSXVertexProgram vertex_program; + u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + vertex_program.data.reserve((512 - transform_program_start) * 4); + + for (int i = transform_program_start; i < 512; ++i) + { + vertex_program.data.resize((i - transform_program_start) * 4 + 4); + memcpy(vertex_program.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32)); + + D3 d3; + d3.HEX = transform_program[i * 4 + 3]; + + if (d3.end) + break; + } + + RSXFragmentProgram fragment_program; + u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; + fragment_program.offset = shader_program & ~0x3; + fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1); + fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; + + gl::glsl::program *result; + __glcheck result = m_prog_buffer.getGraphicPipelineState(&vertex_program, &fragment_program, nullptr, nullptr); + __glcheck result->use(); + + m_program.set_id(result->id()); + +#else + std::vector vertex_program; + u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + vertex_program.reserve((512 - transform_program_start) * 4); + + for (int i = transform_program_start; i < 512; ++i) + { + vertex_program.resize((i - transform_program_start) * 4 + 4); + memcpy(vertex_program.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32)); + + D3 d3; + d3.HEX = transform_program[i * 4 + 3]; + + if (d3.end) + break; + } + + u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; + + std::string fp_shader; ParamArray fp_parr; u32 fp_size; + GLFragmentDecompilerThread decompile_fp(fp_shader, fp_parr, + rsx::get_address(shader_program & ~0x3, (shader_program & 0x3) - 1), fp_size, rsx::method_registers[NV4097_SET_SHADER_CONTROL]); + + std::string vp_shader; ParamArray vp_parr; + GLVertexDecompilerThread decompile_vp(vertex_program, vp_shader, vp_parr); + decompile_fp.Task(); + decompile_vp.Task(); + + LOG_NOTICE(RSX, "fp: %s", fp_shader.c_str()); + LOG_NOTICE(RSX, "vp: %s", vp_shader.c_str()); + + static bool first = true; + gl::glsl::shader fp(gl::glsl::shader::type::fragment, fp_shader); + gl::glsl::shader vp(gl::glsl::shader::type::vertex, vp_shader); + + (m_program.recreate() += { fp.compile(), vp.compile() }).make(); +#endif + + int viewport_x = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] & 0xffff); + int viewport_y = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] & 0xffff); + int viewport_w = int(rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL] >> 16); + int viewport_h = int(rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL] >> 16); + + f32 viewport_offset_x = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 0]; + f32 viewport_offset_y = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 1]; + f32 viewport_offset_z = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 2]; + f32 viewport_offset_w = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 3]; + + f32 viewport_scale_x = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 0]; + f32 viewport_scale_y = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 1]; + f32 viewport_scale_z = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 2]; + f32 viewport_scale_w = (f32&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 3]; + + f32 width = f32(rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16); + f32 height = f32(rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16); + glm::mat4 scaleOffsetMat(1.f); + + //Scale + scaleOffsetMat[0][0] = viewport_scale_x * 2.f / viewport_w; + scaleOffsetMat[1][1] = viewport_scale_y * 2.f / viewport_h; + scaleOffsetMat[2][2] = viewport_scale_z; + + // Offset + scaleOffsetMat[0][3] = viewport_offset_x * 2.f / viewport_w - 1.f; + scaleOffsetMat[1][3] = viewport_offset_y * 2.f / viewport_h - 1.f; + scaleOffsetMat[2][3] = viewport_offset_z - .5f; + + __glcheck m_program.uniforms["scaleOffsetMat"] = scaleOffsetMat; + + for (auto &constant : transform_constants) + { + //LOG_WARNING(RSX, "vc[%u] = (%f, %f, %f, %f)", constant.first, constant.second.r, constant.second.g, constant.second.b, constant.second.a); + __glcheck m_program.uniforms["vc[" + std::to_string(constant.first) + "]"] = constant.second; + } + + for (u32 constant_offset : m_prog_buffer.getFragmentConstantOffsetsCache(&fragment_program)) + { + be_t *data = vm::get_ptr>(fragment_program.addr + constant_offset); u32 c0 = (data[0] >> 16 | data[0] << 16); u32 c1 = (data[1] >> 16 | data[1] << 16); u32 c2 = (data[2] >> 16 | data[2] << 16); u32 c3 = (data[3] >> 16 | data[3] << 16); - const std::string name = fmt::format("fc%u", offsetInFP); - const int l = m_program.GetLocation(name); - checkForGlError("glGetUniformLocation " + name); - float f0 = (float&)c0; - float f1 = (float&)c1; - float f2 = (float&)c2; - float f3 = (float&)c3; - glUniform4f(l, f0, f1, f2, f3); - checkForGlError("glUniform4f " + name + fmt::format(" %u [%f %f %f %f]", l, f0, f1, f2, f3)); - }*/ - -/* for (const RSXTransformConstant& c : m_fragment_constants) - { - u32 id = c.id - m_cur_fragment_prog->offset; - - //LOG_WARNING(RSX,"fc%u[0x%x - 0x%x] = (%f, %f, %f, %f)", id, c.id, m_cur_shader_prog->offset, c.x, c.y, c.z, c.w); - - const std::string name = fmt::format("fc%u", id); - const int l = m_program.GetLocation(name); - checkForGlError("glGetUniformLocation " + name); - - glUniform4f(l, c.x, c.y, c.z, c.w); - checkForGlError("glUniform4f " + name + fmt::format(" %u [%f %f %f %f]", l, c.x, c.y, c.z, c.w)); - }*/ - - - //if (m_fragment_constants.GetCount()) - // LOG_NOTICE(HLE, ""); -} - -bool GLGSRender::LoadProgram() -{ -/* if (!m_cur_fragment_prog) - { - LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL"); - return false; + m_program.uniforms["fc" + std::to_string(constant_offset)] = color4f{ (f32&)c0, (f32&)c1, (f32&)c2, (f32&)c3 }; } - m_cur_fragment_prog->ctrl = m_shader_ctrl; - - if (!m_cur_vertex_prog) - { - LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL"); - return false; - } - - GLProgram *result = m_prog_buffer.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, nullptr, nullptr); - m_program.id = result->id; - m_program.Use();*/ - return true; } -void GLGSRender::WriteBuffers() +struct color_swizzle { - if (Ini.GSDumpDepthBuffer.GetValue()) - { - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - WriteDepthBuffer(); - } + gl::texture::channel a = gl::texture::channel::a; + gl::texture::channel r = gl::texture::channel::r; + gl::texture::channel g = gl::texture::channel::g; + gl::texture::channel b = gl::texture::channel::b; - if (Ini.GSDumpColorBuffers.GetValue()) + color_swizzle() = default; + color_swizzle(gl::texture::channel a, gl::texture::channel r, gl::texture::channel g, gl::texture::channel b) + : a(a), r(r), g(g), b(b) { - WriteColorBuffers(); + } +}; + +struct color_format +{ + gl::texture::type type; + gl::texture::format format; + bool swap_bytes; + int channel_count; + int channel_size; + color_swizzle swizzle; +}; + +color_format surface_color_format_to_gl(int color_format) +{ + //color format + switch (color_format) + { + case CELL_GCM_SURFACE_R5G6B5: + return{ gl::texture::type::ushort_5_6_5, gl::texture::format::bgr, false, 3, 2 }; + + case CELL_GCM_SURFACE_A8R8G8B8: + return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 }; + + case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: + return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1, + { gl::texture::channel::one, gl::texture::channel::r, gl::texture::channel::g, gl::texture::channel::b } }; + + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + return{ gl::texture::type::f16, gl::texture::format::rgba, true, 4, 2 }; + + case CELL_GCM_SURFACE_F_W32Z32Y32X32: + return{ gl::texture::type::f32, gl::texture::format::rgba, true, 4, 4 }; + + case CELL_GCM_SURFACE_B8: + case CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5: + case CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5: + case CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8: + case CELL_GCM_SURFACE_G8B8: + case CELL_GCM_SURFACE_F_X32: + case CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8: + case CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8: + case CELL_GCM_SURFACE_A8B8G8R8: + default: + LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format); + return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 }; } } -void GLGSRender::WriteDepthBuffer() +std::pair surface_depth_format_to_gl(int depth_format) { - - -} - -void GLGSRender::WriteColorBufferA() -{ - -} - -void GLGSRender::WriteColorBufferB() -{ - -} - -void GLGSRender::WriteColorBufferC() -{ - -} - -void GLGSRender::WriteColorBufferD() -{ - -} - -void GLGSRender::WriteColorBuffers() -{ -} - -void GLGSRender::oninit() -{ - m_draw_frames = 1; - m_skip_frames = 0; - last_width = 0; - last_height = 0; - last_depth_format = 0; - -} - -void GLGSRender::oninit_thread() -{ - - InitProcTable(); - - is_intel_vendor = strstr((const char*)glGetString(GL_VENDOR), "Intel"); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - - glGenTextures(1, &g_depth_tex); - glGenTextures(1, &g_flip_tex); - glGenBuffers(6, g_pbo); // 4 for color buffers + 1 for depth buffer + 1 for flip() - -#ifdef _WIN32 - glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0); -#endif - -} - -void GLGSRender::onexit_thread() -{ - glDeleteTextures(1, &g_flip_tex); - glDeleteTextures(1, &g_depth_tex); - glDeleteBuffers(6, g_pbo); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); - - m_program.Delete(); - m_rbo.Delete(); - m_fbo.Delete(); - m_vbo.Delete(); - m_vao.Delete(); -} - -void GLGSRender::OnReset() -{ - m_program.UnUse(); - - if (m_vbo.IsCreated()) + switch (depth_format) { - m_vbo.UnBind(); - m_vbo.Delete(); + case CELL_GCM_SURFACE_Z16: + return std::make_pair(gl::texture::type::ushort, gl::texture::format::depth); + + default: + LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", depth_format); + case CELL_GCM_SURFACE_Z24S8: + return std::make_pair(gl::texture::type::uint_24_8, gl::texture::format::depth_stencil); + //return std::make_pair(gl::texture::type::f32, gl::texture::format::depth); } - - m_vao.Delete(); } -void GLGSRender::InitDrawBuffers() +void GLGSRender::init_buffers() { -// if (!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format) + u32 surface_format = rsx::method_registers[NV4097_SET_SURFACE_FORMAT]; + + u32 clip_horizontal = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL]; + u32 clip_vertical = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL]; + + u32 clip_width = clip_horizontal >> 16; + u32 clip_height = clip_vertical >> 16; + u32 clip_x = clip_horizontal; + u32 clip_y = clip_vertical; + + if (!draw_fbo || m_surface.format != surface_format) { -// last_depth_format = m_surface_depth_format; + m_surface.unpack(surface_format); + m_surface.width = clip_width; + m_surface.height = clip_height; - m_fbo.Create(); - checkForGlError("m_fbo.Create"); - m_fbo.Bind(); + LOG_WARNING(RSX, "surface: %dx%d", clip_width, clip_height); - m_rbo.Create(4 + 1); - checkForGlError("m_rbo.Create"); + draw_fbo.recreate(); + m_draw_tex_depth_stencil.recreate(gl::texture::target::texture2D); - for (int i = 0; i < 4; ++i) + auto format = surface_color_format_to_gl(m_surface.color_format); + + for (int i = 0; i < rsx::limits::color_buffers_count; ++i) { - m_rbo.Bind(i); - checkForGlError("m_rbo.Storage(GL_RGBA)"); - } + m_draw_tex_color[i].recreate(gl::texture::target::texture2D); + __glcheck m_draw_tex_color[i].config() + .size({ (int)m_surface.width, (int)m_surface.height }) + .type(format.type) + .format(format.format) + .swizzle(format.swizzle.r, format.swizzle.g, format.swizzle.b, format.swizzle.a); - m_rbo.Bind(4); + __glcheck m_draw_tex_color[i].pixel_pack_settings().swap_bytes(format.swap_bytes).aligment(1); + __glcheck m_draw_tex_color[i].pixel_unpack_settings().swap_bytes(format.swap_bytes).aligment(1); + + __glcheck draw_fbo.color[i] = m_draw_tex_color[i]; + __glcheck draw_fbo.check(); + } switch (m_surface.depth_format) { - case 0: - { - // case 0 found in BLJM60410-[Suzukaze no Melt - Days in the Sanctuary] - // [E : RSXThread]: Bad depth format! (0) - // [E : RSXThread]: glEnable: opengl error 0x0506 - // [E : RSXThread]: glDrawArrays: opengl error 0x0506 - checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)"); - break; - } - case CELL_GCM_SURFACE_Z16: { - checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); + __glcheck m_draw_tex_depth_stencil.config() + .size({ (int)m_surface.width, (int)m_surface.height }) + .type(gl::texture::type::ushort) + .format(gl::texture::format::depth) + .internal_format(gl::texture::internal_format::depth16); - m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); + __glcheck draw_fbo.depth = m_draw_tex_depth_stencil; break; } - case CELL_GCM_SURFACE_Z24S8: { - checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); - - m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); - - m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); - checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); + __glcheck m_draw_tex_depth_stencil.config() + .size({ (int)m_surface.width, (int)m_surface.height }) + .type(gl::texture::type::uint_24_8) + .format(gl::texture::format::depth_stencil) + .internal_format(gl::texture::internal_format::depth24_stencil8); + __glcheck draw_fbo.depth_stencil = m_draw_tex_depth_stencil; break; - } - + + case 0: + break; default: { -// LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format); + LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface.depth_format); assert(0); break; } } - for (int i = 0; i < 4; ++i) - { - m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); - checkForGlError(fmt::format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); - } - - //m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); - //checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); - - //if (m_surface_depth_format == 2) - //{ - // m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); - // checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); - //} + __glcheck m_draw_tex_depth_stencil.pixel_pack_settings().aligment(1); + __glcheck m_draw_tex_depth_stencil.pixel_unpack_settings().aligment(1); } - if (!m_set_surface_clip_horizontal) + if (clear_surface_buffers == gl::buffers::none) { -// m_surface_clip_x = 0; -// m_surface_clip_w = RSXThread::m_width; - } - - if (!m_set_surface_clip_vertical) - { -// m_surface_clip_y = 0; -// m_surface_clip_h = RSXThread::m_height; - } - - m_fbo.Bind(); - - static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; - - switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) - { - case CELL_GCM_SURFACE_TARGET_NONE: break; - - case CELL_GCM_SURFACE_TARGET_0: - { - glDrawBuffer(draw_buffers[0]); - checkForGlError("glDrawBuffer(0)"); - break; - } - - case CELL_GCM_SURFACE_TARGET_1: - { - glDrawBuffer(draw_buffers[1]); - checkForGlError("glDrawBuffer(1)"); - break; - } - - case CELL_GCM_SURFACE_TARGET_MRT1: - { - glDrawBuffers(2, draw_buffers); - checkForGlError("glDrawBuffers(2)"); - break; - } - - case CELL_GCM_SURFACE_TARGET_MRT2: - { - glDrawBuffers(3, draw_buffers); - checkForGlError("glDrawBuffers(3)"); - break; - } - - case CELL_GCM_SURFACE_TARGET_MRT3: - { - glDrawBuffers(4, draw_buffers); - checkForGlError("glDrawBuffers(4)"); - break; - } - - default: - { - LOG_ERROR(RSX, "Bad surface color target: %d", color_target); - break; - } - - } - - if (m_read_buffer) - { - u32 format = GL_BGRA; - CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); - u32 addr = rsx::get_address(buffers[gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); - u32 width = buffers[gcm_current_buffer].width; - u32 height = buffers[gcm_current_buffer].height; - glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, vm::get_ptr(addr)); - } -} - -bool GLGSRender::domethod(u32 arg, u32) -{ - return false; - InitDrawBuffers(); - -// if (m_set_color_mask) - { -// glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); - checkForGlError("glColorMask"); - } - - if (m_set_scissor_horizontal && m_set_scissor_vertical) - { - glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); - } - - GLbitfield f = 0; - - if (m_clear_surface_mask & 0x1) - { -// glClearDepth(m_clear_surface_z / (float)0xffffff); - checkForGlError("glClearDepth"); - - f |= GL_DEPTH_BUFFER_BIT; - } - - if (m_clear_surface_mask & 0x2) - { -// glClearStencil(m_clear_surface_s); - checkForGlError("glClearStencil"); - - f |= GL_STENCIL_BUFFER_BIT; - } - - if (m_clear_surface_mask & 0xF0) - { -/* glClearColor( - m_clear_surface_color_r / 255.0f, - m_clear_surface_color_g / 255.0f, - m_clear_surface_color_b / 255.0f, - m_clear_surface_color_a / 255.0f);*/ - checkForGlError("glClearColor"); - - f |= GL_COLOR_BUFFER_BIT; - } - - glClear(f); - checkForGlError("glClear"); - - WriteBuffers(); -} - -void GLGSRender::end() -{ - //return; - if (!LoadProgram()) - { - LOG_ERROR(RSX, "LoadProgram failed."); - Emu.Pause(); - return; - } - - InitDrawBuffers(); - -// if (m_set_color_mask) - { -// glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); - checkForGlError("glColorMask"); - } - - if (!m_indexed_array.m_count && !draw_array_count) - { - u32 min_vertex_size = ~0; -/* for (auto &i : m_vertex_data) - { - if (!i.size) - continue; - - u32 vertex_size = i.data.size() / (i.size * rsx::get_vertex_type_size(i.type)); - - if (min_vertex_size > vertex_size) - min_vertex_size = vertex_size; - }*/ - - draw_array_count = min_vertex_size; - draw_array_first = 0; - } - -// Enable(m_set_depth_test, GL_DEPTH_TEST); -// Enable(m_set_alpha_test, GL_ALPHA_TEST); -// Enable(m_set_blend || m_set_blend_mrt1 || m_set_blend_mrt2 || m_set_blend_mrt3, GL_BLEND); - Enable(m_set_scissor_horizontal && m_set_scissor_vertical, GL_SCISSOR_TEST); -// Enable(m_set_logic_op, GL_LOGIC_OP); -// Enable(m_set_cull_face, GL_CULL_FACE); - Enable(m_set_dither, GL_DITHER); -// Enable(m_set_stencil_test, GL_STENCIL_TEST); - Enable(m_set_line_smooth, GL_LINE_SMOOTH); - Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); - Enable(m_set_point_sprite_control, GL_POINT_SPRITE); - Enable(m_set_specular, GL_LIGHTING); - Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL); - Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE); - Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT); - Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); - Enable(m_set_line_stipple, GL_LINE_STIPPLE); - Enable(m_set_polygon_stipple, GL_POLYGON_STIPPLE); - - if (!is_intel_vendor) - { - Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT); - } - - if (m_set_clip_plane) - { - Enable(m_clip_plane_0, GL_CLIP_PLANE0); - Enable(m_clip_plane_1, GL_CLIP_PLANE1); - Enable(m_clip_plane_2, GL_CLIP_PLANE2); - Enable(m_clip_plane_3, GL_CLIP_PLANE3); - Enable(m_clip_plane_4, GL_CLIP_PLANE4); - Enable(m_clip_plane_5, GL_CLIP_PLANE5); - - checkForGlError("m_set_clip_plane"); - } - - checkForGlError("glEnable"); - - if (m_set_front_polygon_mode) - { - glPolygonMode(GL_FRONT, m_front_polygon_mode); - checkForGlError("glPolygonMode(Front)"); - } - - if (m_set_back_polygon_mode) - { - glPolygonMode(GL_BACK, m_back_polygon_mode); - checkForGlError("glPolygonMode(Back)"); - } - - if (m_set_point_size) - { - glPointSize(m_point_size); - checkForGlError("glPointSize"); - } - - if (m_set_poly_offset_mode) - { - glPolygonOffset(m_poly_offset_scale_factor, m_poly_offset_bias); - checkForGlError("glPolygonOffset"); - } - -// if (m_set_logic_op) - { -// glLogicOp(m_logic_op); - checkForGlError("glLogicOp"); - } - - if (m_set_scissor_horizontal && m_set_scissor_vertical) - { - glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); - } - -/* if (m_set_two_sided_stencil_test_enable) - { - if (m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) - { - glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); - checkForGlError("glStencilOpSeparate"); - } - - if (m_set_stencil_mask) - { - glStencilMaskSeparate(GL_FRONT, m_stencil_mask); - checkForGlError("glStencilMaskSeparate"); - } - - if (m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) - { - glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - checkForGlError("glStencilFuncSeparate"); - } - - if (m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass) - { - glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); - checkForGlError("glStencilOpSeparate(GL_BACK)"); - } - - if (m_set_back_stencil_mask) - { - glStencilMaskSeparate(GL_BACK, m_back_stencil_mask); - checkForGlError("glStencilMaskSeparate(GL_BACK)"); - } - - if (m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask) - { - glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); - checkForGlError("glStencilFuncSeparate(GL_BACK)"); - } - } - else - { - if (m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) - { - glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); - checkForGlError("glStencilOp"); - } - - if (m_set_stencil_mask) - { - glStencilMask(m_stencil_mask); - checkForGlError("glStencilMask"); - } - - if (m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) - { - glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); - checkForGlError("glStencilFunc"); - } - }*/ - - // TODO: Use other glLightModel functions? - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, m_set_two_side_light_enable ? GL_TRUE : GL_FALSE); - checkForGlError("glLightModeli"); - - if (m_set_shade_mode) - { - glShadeModel(m_shade_mode); - checkForGlError("glShadeModel"); - } - -// if (m_set_depth_mask) - { -// glDepthMask(m_depth_mask); - checkForGlError("glDepthMask"); - } - -// if (m_set_depth_func) - { -// glDepthFunc(m_depth_func); - checkForGlError("glDepthFunc"); - } - - if (m_set_depth_bounds && !is_intel_vendor) - { - glDepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max); - checkForGlError("glDepthBounds"); - } - - if (m_set_clip) - { - glDepthRangef(m_clip_min, m_clip_max); - checkForGlError("glDepthRangef"); - } - - if (m_set_line_width) - { - glLineWidth(m_line_width); - checkForGlError("glLineWidth"); - } - - if (m_set_line_stipple) - { - glLineStipple(m_line_stipple_factor, m_line_stipple_pattern); - checkForGlError("glLineStipple"); - } - - if (m_set_polygon_stipple) - { - glPolygonStipple((const GLubyte*)m_polygon_stipple_pattern); - checkForGlError("glPolygonStipple"); - } - -// if (m_set_blend_equation) - { -// glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha); - checkForGlError("glBlendEquationSeparate"); - } - -// if (m_set_blend_sfactor && m_set_blend_dfactor) - { -// glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); - checkForGlError("glBlendFuncSeparate"); - } - -// if (m_set_blend_color) - { -// glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); - checkForGlError("glBlendColor"); - } - -// if (m_set_cull_face) - { -// glCullFace(m_cull_face); - checkForGlError("glCullFace"); - } - -// if (m_set_front_face) - { -// glFrontFace(m_front_face); - checkForGlError("glFrontFace"); - } - -// if (m_set_alpha_func && m_set_alpha_ref) - { -// glAlphaFunc(m_alpha_func, m_alpha_ref); - checkForGlError("glAlphaFunc"); - } - - if (m_set_fog_mode) - { - glFogi(GL_FOG_MODE, m_fog_mode); - checkForGlError("glFogi(GL_FOG_MODE)"); - } - - if (m_set_fog_params) - { - glFogf(GL_FOG_START, m_fog_param0); - checkForGlError("glFogf(GL_FOG_START)"); - glFogf(GL_FOG_END, m_fog_param1); - checkForGlError("glFogf(GL_FOG_END)"); - } - - if (m_set_restart_index) - { - glPrimitiveRestartIndex(m_restart_index); - checkForGlError("glPrimitiveRestartIndex"); - } - - if (m_indexed_array.m_count && draw_array_count) - { - LOG_WARNING(RSX, "m_indexed_array.m_count && draw_array_count"); - } - - for (u32 i = 0; i < rsx::limits::textures_count; ++i) - { - if (!textures[i].enabled()) continue; - - glActiveTexture(GL_TEXTURE0 + i); - checkForGlError("glActiveTexture"); - m_gl_textures[i].Create(); - m_gl_textures[i].Bind(); - checkForGlError(fmt::format("m_gl_textures[%d].Bind", i)); - m_program.SetTex(i); - m_gl_textures[i].Init(textures[i]); - checkForGlError(fmt::format("m_gl_textures[%d].Init", i)); - } - - for (u32 i = 0; i < rsx::limits::vertex_textures_count; ++i) - { - if (!m_vertex_textures[i].enabled()) continue; - - glActiveTexture(GL_TEXTURE0 + rsx::limits::textures_count + i); - checkForGlError("glActiveTexture"); - m_gl_vertex_textures[i].Create(); - m_gl_vertex_textures[i].Bind(); - checkForGlError(fmt::format("m_gl_vertex_textures[%d].Bind", i)); - m_program.SetVTex(i); -// m_gl_vertex_textures[i].Init(m_vertex_textures[i]); - checkForGlError(fmt::format("m_gl_vertex_textures[%d].Init", i)); - } - - m_vao.Bind(); - -/* if (m_indexed_array.m_count) - LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); - else - LoadVertexData(draw_array_first, draw_array_count);*/ - - if (m_indexed_array.m_count || draw_array_count) - { - EnableVertexData(m_indexed_array.m_count ? true : false); - - InitVertexData(); - InitFragmentData(); - } - - if (m_indexed_array.m_count) - { - switch(m_indexed_array.m_type) - { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - glDrawElements(draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); - checkForGlError("glDrawElements #4"); - break; - - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - glDrawElements(draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); - checkForGlError("glDrawElements #2"); - break; - - default: - LOG_ERROR(RSX, "Bad indexed array type (%d)", m_indexed_array.m_type); - break; - } - - DisableVertexData(); - m_indexed_array.Reset(); - } - - if (draw_array_count) - { - //LOG_WARNING(RSX,"glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, m_draw_array_count); - glDrawArrays(draw_mode - 1, 0, draw_array_count); - checkForGlError("glDrawArrays"); - DisableVertexData(); - } - - WriteBuffers(); -} - -void GLGSRender::flip(int buffer) -{ - // Set scissor to FBO size - if (m_set_scissor_horizontal && m_set_scissor_vertical) - { - checkForGlError("glScissor"); + read_buffers(); } switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) { + case CELL_GCM_SURFACE_TARGET_NONE: break; + case CELL_GCM_SURFACE_TARGET_0: + __glcheck draw_fbo.draw_buffer(draw_fbo.color[0]); + break; + case CELL_GCM_SURFACE_TARGET_1: + __glcheck draw_fbo.draw_buffer(draw_fbo.color[1] ); + break; + case CELL_GCM_SURFACE_TARGET_MRT1: + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1] }); + break; + case CELL_GCM_SURFACE_TARGET_MRT2: + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2] }); + break; + case CELL_GCM_SURFACE_TARGET_MRT3: - { - // Fast path for non-MRT using glBlitFramebuffer. - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); - // Renderbuffer is upside turn , swapped srcY0 and srcY1 - } + __glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2], draw_fbo.color[3] }); break; - case CELL_GCM_SURFACE_TARGET_NONE: - { - // Slow path for MRT/None target using glReadPixels. - static u8* src_buffer = nullptr; - static u32 width = 0; - static u32 height = 0; - GLenum format = GL_RGBA; + default: + LOG_ERROR(RSX, "Bad surface color target: %d", rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]); + break; + } - if (m_read_buffer) + if (clear_surface_buffers != gl::buffers::none) + { + //draw_fbo.clear(clear_surface_buffers); + + clear_surface_buffers = gl::buffers::none; + } +} + +static const u32 mr_color_offset[rsx::limits::color_buffers_count] = +{ + NV4097_SET_SURFACE_COLOR_AOFFSET, + NV4097_SET_SURFACE_COLOR_BOFFSET, + NV4097_SET_SURFACE_COLOR_COFFSET, + NV4097_SET_SURFACE_COLOR_DOFFSET +}; + +static const u32 mr_color_dma[rsx::limits::color_buffers_count] = +{ + NV4097_SET_CONTEXT_DMA_COLOR_A, + NV4097_SET_CONTEXT_DMA_COLOR_B, + NV4097_SET_CONTEXT_DMA_COLOR_C, + NV4097_SET_CONTEXT_DMA_COLOR_D +}; + +void GLGSRender::read_buffers() +{ + if (!draw_fbo) + return; + + glDisable(GL_STENCIL_TEST); + + if (Ini.GSReadColorBuffers.GetValue()) + { + auto color_format = surface_color_format_to_gl(m_surface.color_format); + + auto read_color_buffers = [&](int index, int count) { - format = GL_BGRA; - CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); - u32 addr = rsx::get_address(buffers[gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); - width = buffers[gcm_current_buffer].width; - height = buffers[gcm_current_buffer].height; - src_buffer = vm::get_ptr(addr); - } - else if (m_fbo.IsCreated()) - { - format = GL_RGBA; - static std::vector pixels; - m_fbo.Bind(GL_READ_FRAMEBUFFER); - glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[5]); - checkForGlError("Flip(): glReadPixels(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8)"); - GLubyte *packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); - if (packed) + for (int i = index; i < index + count; ++i) { - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - checkForGlError("Flip(): glUnmapBuffer"); + u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); + __glcheck m_draw_tex_color[i].copy_from(vm::get_ptr(color_address), color_format.format, color_format.type); } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + }; - src_buffer = pixels.data(); - } - else + switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) { - src_buffer = nullptr; + case CELL_GCM_SURFACE_TARGET_NONE: + break; + + case CELL_GCM_SURFACE_TARGET_0: + read_color_buffers(0, 1); + break; + + case CELL_GCM_SURFACE_TARGET_1: + read_color_buffers(1, 1); + break; + + case CELL_GCM_SURFACE_TARGET_MRT1: + read_color_buffers(0, 2); + break; + + case CELL_GCM_SURFACE_TARGET_MRT2: + read_color_buffers(0, 3); + break; + + case CELL_GCM_SURFACE_TARGET_MRT3: + read_color_buffers(0, 4); + break; } - - if (src_buffer) + } + + if (Ini.GSReadDepthBuffer.GetValue()) + { + auto depth_format = surface_depth_format_to_gl(m_surface.depth_format); + + int pixel_size = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 2 : 4; + + gl::buffer pbo_depth; + + __glcheck pbo_depth.create(m_surface.width * m_surface.height * pixel_size); + __glcheck pbo_depth.map([&](GLubyte* pixels) { - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CLIP_PLANE0); - glDisable(GL_CLIP_PLANE1); - glDisable(GL_CLIP_PLANE2); - glDisable(GL_CLIP_PLANE3); - glDisable(GL_CLIP_PLANE4); - glDisable(GL_CLIP_PLANE5); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, g_flip_tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_INT_8_8_8_8, src_buffer); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, 1, 0, 1, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + if (m_surface.depth_format == CELL_GCM_SURFACE_Z16) + { + u16 *dst = (u16*)pixels; + const be_t* src = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + else + { + u32 *dst = (u32*)pixels; + const be_t* src = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + }, gl::buffer::access::write); - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); + __glcheck m_draw_tex_depth_stencil.copy_from(pbo_depth, depth_format.second, depth_format.first); + } +} - m_program.UnUse(); - m_program.Use(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); +void GLGSRender::write_buffers() +{ + if (!draw_fbo) + return; - glColor3f(1, 1, 1); - glBegin(GL_QUADS); - glTexCoord2i(0, 1); - glVertex2i(0, 0); - glTexCoord2i(1, 1); - glVertex2i(1, 0); - glTexCoord2i(1, 0); - glVertex2i(1, 1); - glTexCoord2i(0, 0); - glVertex2i(0, 1); - glEnd(); + if (Ini.GSDumpColorBuffers.GetValue()) + { + //gl::buffer pbo_color; + //__glcheck pbo_color.create(m_draw_tex_color[0].width() * m_draw_tex_color[0].height() * 4); + + auto color_format = surface_color_format_to_gl(m_surface.color_format); + + auto write_color_buffers = [&](int index, int count) + { + for (int i = index; i < index + count; ++i) + { + //TODO: swizzle + //__glcheck m_draw_tex_color[i].copy_to(pbo_color, color_format.format, color_format.type); + + //pbo_color.map([&](GLubyte* pixels) + //{ + // u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); + // //u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); + + // const u32 *src = (const u32*)pixels; + // be_t* dst = vm::get_ptr>(color_address); + // for (int i = 0, end = m_draw_tex_color[i].width() * m_draw_tex_color[i].height(); i < end; ++i) + // { + // dst[i] = src[i]; + // } + + //}, gl::buffer::access::read); + + u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); + __glcheck m_draw_tex_color[i].copy_to(vm::get_ptr(color_address), color_format.format, color_format.type); + } + }; + + switch (rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) + { + case CELL_GCM_SURFACE_TARGET_NONE: + break; + + case CELL_GCM_SURFACE_TARGET_0: + write_color_buffers(0, 1); + break; + + case CELL_GCM_SURFACE_TARGET_1: + write_color_buffers(1, 1); + break; + + case CELL_GCM_SURFACE_TARGET_MRT1: + write_color_buffers(0, 2); + break; + + case CELL_GCM_SURFACE_TARGET_MRT2: + write_color_buffers(0, 3); + break; + + case CELL_GCM_SURFACE_TARGET_MRT3: + write_color_buffers(0, 4); + break; } } - break; - } - // Draw Objects - for (uint i = 0; i < m_post_draw_objs.size(); ++i) + if (Ini.GSDumpDepthBuffer.GetValue()) { - m_post_draw_objs[i].Draw(); + auto depth_format = surface_depth_format_to_gl(m_surface.depth_format); + + gl::buffer pbo_depth; + + int pixel_size = m_surface.depth_format == CELL_GCM_SURFACE_Z16 ? 2 : 4; + + __glcheck pbo_depth.create(m_surface.width * m_surface.height * pixel_size); + __glcheck m_draw_tex_depth_stencil.copy_to(pbo_depth, depth_format.second, depth_format.first); + + __glcheck pbo_depth.map([&](GLubyte* pixels) + { + u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); + + if (m_surface.depth_format == CELL_GCM_SURFACE_Z16) + { + const u16 *src = (const u16*)pixels; + be_t* dst = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + else + { + const u32 *src = (const u32*)pixels; + be_t* dst = vm::get_ptr>(depth_address); + for (int i = 0, end = m_draw_tex_depth_stencil.width() * m_draw_tex_depth_stencil.height(); i < end; ++i) + { + dst[i] = src[i]; + } + } + + }, gl::buffer::access::read); } +} - // m_frame->Flip(m_context); +void GLGSRender::flip(int buffer) +{ + LOG_NOTICE(Log::RSX, "flip(%d)", buffer); + u32 buffer_width = gcm_buffers[buffer].width; + u32 buffer_height = gcm_buffers[buffer].height; + u32 buffer_pitch = gcm_buffers[buffer].pitch; + u32 buffer_address = rsx::get_address(gcm_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL); + bool skip_read = false; - // Restore scissor - if (m_set_scissor_horizontal && m_set_scissor_vertical) + if (draw_fbo && !Ini.GSDumpColorBuffers.GetValue()) { - glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); + skip_read = true; + /* + for (uint i = 0; i < rsx::limits::color_buffers_count; ++i) + { + u32 color_address = rsx::get_address(rsx::method_registers[mr_color_offset[i]], rsx::method_registers[mr_color_dma[i]]); + + if (color_address == buffer_address) + { + skip_read = true; + __glcheck draw_fbo.draw_buffer(draw_fbo.color[i]); + break; + } + } + */ } + if (!skip_read) + { + if (!m_flip_tex_color || m_flip_tex_color.size() != sizei{ (int)buffer_width, (int)buffer_height }) + { + m_flip_tex_color.recreate(gl::texture::target::texture2D); + + __glcheck m_flip_tex_color.config() + .size({ (int)buffer_width, (int)buffer_height }) + .type(gl::texture::type::uint_8_8_8_8) + .format(gl::texture::format::bgra); + + m_flip_tex_color.pixel_unpack_settings().aligment(1); + m_flip_tex_color.pixel_pack_settings().aligment(1); + + __glcheck m_flip_fbo.recreate(); + __glcheck m_flip_fbo.color = m_flip_tex_color; + } + + __glcheck m_flip_fbo.draw_buffer(m_flip_fbo.color); + + m_flip_fbo.bind(); + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + glDisable(GL_LOGIC_OP); + glDisable(GL_CULL_FACE); + + __glcheck m_flip_tex_color.copy_from(vm::get_ptr(buffer_address), + gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8); + } + + areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height }); + + coordi aspect_ratio; + if (1) //enable aspect ratio + { + sizei csize = m_frame->client_size(); + sizei new_size = csize; + + const double aq = (double)buffer_width / buffer_height; + const double rq = (double)new_size.width / new_size.height; + const double q = aq / rq; + + if (q > 1.0) + { + new_size.height = int(new_size.height / q); + aspect_ratio.y = (csize.height - new_size.height) / 2; + } + else if (q < 1.0) + { + new_size.width = int(new_size.width * q); + aspect_ratio.x = (csize.width - new_size.width) / 2; + } + + aspect_ratio.size = new_size; + } + else + { + aspect_ratio.size = m_frame->client_size(); + } + + gl::screen.clear(gl::buffers::color_depth_stencil); + + if (!skip_read) + { + __glcheck m_flip_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical()); + } + else + { + __glcheck draw_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical()); + } + + m_frame->flip(m_context); } -void GLGSRender::semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) -{ - vm::ps3::write32(label_addr + offset, value); -} -void GLGSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) +u64 GLGSRender::timestamp() const { - vm::ps3::write32(label_addr + offset, value); -} - -void GLGSRender::semaphorePFIFOAcquire(u32 offset, u32 value) -{ - + GLint64 result; + glGetInteger64v(GL_TIMESTAMP, &result); + return result; } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 3b718029ee..d6ddd033cf 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -1,183 +1,101 @@ #pragma once #include "Emu/RSX/GSRender.h" #include "GLBuffers.h" +#include "gl_helpers.h" #define RSX_DEBUG 1 - #include "GLProgramBuffer.h" #pragma comment(lib, "opengl32.lib") -#if RSX_DEBUG -#define checkForGlError(sit) if((g_last_gl_error = glGetError()) != GL_NO_ERROR) printGlError(g_last_gl_error, sit) -#else -#define checkForGlError(sit) -#endif - -extern GLenum g_last_gl_error; -void printGlError(GLenum err, const char* situation); -void printGlError(GLenum err, const std::string& situation); - - class GLTexture { - u32 m_id; + u32 m_id = 0; public: - GLTexture() : m_id(0) - { - } + void create(); - void Create(); + int gl_wrap(int wrap); - int GetGlWrap(int wrap); + float max_aniso(int aniso); - float GetMaxAniso(int aniso); - - inline static u8 Convert4To8(u8 v) + inline static u8 convert_4_to_8(u8 v) { // Swizzle bits: 00001234 -> 12341234 return (v << 4) | (v); } - inline static u8 Convert5To8(u8 v) + inline static u8 convert_5_to_8(u8 v) { // Swizzle bits: 00012345 -> 12345123 return (v << 3) | (v >> 2); } - inline static u8 Convert6To8(u8 v) + inline static u8 convert_6_to_8(u8 v) { // Swizzle bits: 00123456 -> 12345612 return (v << 2) | (v >> 4); } - void Init(rsx::texture& tex); + void init(rsx::texture& tex); + void save(rsx::texture& tex, const std::string& name); + void save(rsx::texture& tex); + void bind(); + void unbind(); + void remove(); - void Save(rsx::texture& tex, const std::string& name); - - void Save(rsx::texture& tex); - - void Bind(); - - void Unbind(); - - void Delete(); + u32 id() const; }; -class PostDrawObj -{ -protected: - GLFragmentProgram m_fp; - GLVertexProgram m_vp; - GLProgram m_program; - GLfbo m_fbo; - GLrbo m_rbo; - -public: - virtual void Draw(); - - virtual void InitializeShaders() = 0; - virtual void InitializeLocations() = 0; - - void Initialize(); -}; - -class DrawCursorObj : public PostDrawObj -{ - u32 m_tex_id; - void* m_pixels; - u32 m_width, m_height; - double m_pos_x, m_pos_y, m_pos_z; - bool m_update_texture, m_update_pos; - -public: - DrawCursorObj() : PostDrawObj() - , m_tex_id(0) - , m_update_texture(false) - , m_update_pos(false) - { - } - - virtual void Draw(); - - virtual void InitializeShaders(); - - void SetTexture(void* pixels, int width, int height); - - void SetPosition(float x, float y, float z = 0.0f); - - void InitializeLocations(); -}; - -class GLGSRender final : public GSRender +class GLGSRender : public GSRender { private: - std::vector m_vdata; - std::vector m_post_draw_objs; - - GLProgram m_program; - int m_fp_buf_num; - int m_vp_buf_num; - GLProgramBuffer m_prog_buffer; - GLFragmentProgram m_fragment_prog; GLVertexProgram m_vertex_prog; GLTexture m_gl_textures[rsx::limits::textures_count]; GLTexture m_gl_vertex_textures[rsx::limits::vertex_textures_count]; - GLvao m_vao; - GLvbo m_vbo; - GLrbo m_rbo; - GLfbo m_fbo; + //TODO: program cache + gl::glsl::program m_program; - void* m_context; + rsx::surface_info m_surface; public: - u32 m_draw_frames; - u32 m_skip_frames; - bool is_intel_vendor; - - GLGSRender(); - virtual ~GLGSRender() override; + gl::fbo draw_fbo; + gl::buffers clear_surface_buffers = gl::buffers::none; private: - void EnableVertexData(bool indexed_draw = false); - void DisableVertexData(); - void InitVertexData(); - void InitFragmentData(); + GLProgramBuffer m_prog_buffer; - void Enable(bool enable, const u32 cap); + gl::texture m_draw_tex_color[rsx::limits::color_buffers_count]; + gl::texture m_draw_tex_depth_stencil; - bool LoadProgram(); - void WriteBuffers(); - void WriteDepthBuffer(); - void WriteColorBuffers(); - void WriteColorBufferA(); - void WriteColorBufferB(); - void WriteColorBufferC(); - void WriteColorBufferD(); + //buffer + gl::fbo m_flip_fbo; + gl::texture m_flip_tex_color; - void DrawObjects(); - void InitDrawBuffers(); +public: + GLGSRender(); + +private: + static u32 enable(u32 enable, u32 cap); + static u32 enable(u32 enable, u32 cap, u32 index); + +public: + bool load_program(); + void init_buffers(); + void read_buffers(); + void write_buffers(); protected: - virtual void oninit() override; - virtual void oninit_thread() override; - virtual void onexit_thread() override; - virtual void OnReset() override; - virtual bool domethod(u32, u32) override; - virtual void end() override; - virtual void flip(int buffer) override; + void begin() override; + void end() override; - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override; - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override; - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override; - - virtual void notifyProgramChange() override {} - virtual void notifyBlendStateChange() override {} - virtual void notifyDepthStencilStateChange() override {} - virtual void notifyRasterizerStateChange() override {} + void oninit_thread() override; + void onexit_thread() override; + bool domethod(u32 id, u32 arg) override; + void flip(int buffer) override; + u64 timestamp() const override; }; diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index 22a6a004ab..83cd07262d 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -23,25 +23,12 @@ OPENGL_PROC(PFNGLATTACHSHADERPROC, AttachShader); OPENGL_PROC(PFNGLDETACHSHADERPROC, DetachShader); OPENGL_PROC(PFNGLGETATTRIBLOCATIONPROC, GetAttribLocation); OPENGL_PROC(PFNGLLINKPROGRAMPROC, LinkProgram); -//OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, BindFragDataLocation); +OPENGL_PROC(PFNGLVALIDATEPROGRAMPROC, ValidateProgram); +OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, BindFragDataLocation); OPENGL_PROC(PFNGLBINDATTRIBLOCATIONPROC, BindAttribLocation); OPENGL_PROC(PFNGLGETUNIFORMLOCATIONPROC, GetUniformLocation); OPENGL_PROC(PFNGLGETPROGRAMIVPROC, GetProgramiv); OPENGL_PROC(PFNGLGETPROGRAMINFOLOGPROC, GetProgramInfoLog); -OPENGL_PROC(PFNGLVERTEXATTRIB4BVPROC, VertexAttrib4bv); -OPENGL_PROC(PFNGLVERTEXATTRIB4UBVPROC, VertexAttrib4ubv); -OPENGL_PROC(PFNGLVERTEXATTRIB1SPROC, VertexAttrib1s); -OPENGL_PROC(PFNGLVERTEXATTRIB2SVPROC, VertexAttrib2sv); -OPENGL_PROC(PFNGLVERTEXATTRIB3SVPROC, VertexAttrib3sv); -OPENGL_PROC(PFNGLVERTEXATTRIB4SVPROC, VertexAttrib4sv); -OPENGL_PROC(PFNGLVERTEXATTRIB4IVPROC, VertexAttrib4iv); -OPENGL_PROC(PFNGLVERTEXATTRIB1FPROC, VertexAttrib1f); -OPENGL_PROC(PFNGLVERTEXATTRIB2FPROC, VertexAttrib2f); -OPENGL_PROC(PFNGLVERTEXATTRIB3FPROC, VertexAttrib3f); -OPENGL_PROC(PFNGLVERTEXATTRIB4FPROC, VertexAttrib4f); -OPENGL_PROC(PFNGLVERTEXATTRIB2FVPROC, VertexAttrib2fv); -OPENGL_PROC(PFNGLVERTEXATTRIB3FVPROC, VertexAttrib3fv); -OPENGL_PROC(PFNGLVERTEXATTRIB4FVPROC, VertexAttrib4fv); OPENGL_PROC(PFNGLVERTEXATTRIBPOINTERPROC, VertexAttribPointer); OPENGL_PROC(PFNGLENABLEVERTEXATTRIBARRAYPROC, EnableVertexAttribArray); OPENGL_PROC(PFNGLDISABLEVERTEXATTRIBARRAYPROC, DisableVertexAttribArray); @@ -49,36 +36,106 @@ OPENGL_PROC(PFNGLGENVERTEXARRAYSPROC, GenVertexArrays); OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, BindVertexArray); OPENGL_PROC(PFNGLDELETEVERTEXARRAYSPROC, DeleteVertexArrays); OPENGL_PROC(PFNGLDEPTHRANGEFPROC, DepthRangef); + +OPENGL_PROC(PFNGLVERTEXATTRIB1FPROC, VertexAttrib1f); +OPENGL_PROC(PFNGLVERTEXATTRIB1DPROC, VertexAttrib1d); +OPENGL_PROC(PFNGLVERTEXATTRIB1FVPROC, VertexAttrib1fv); +OPENGL_PROC(PFNGLVERTEXATTRIB1DVPROC, VertexAttrib1dv); +OPENGL_PROC(PFNGLVERTEXATTRIB2FPROC, VertexAttrib2f); +OPENGL_PROC(PFNGLVERTEXATTRIB2DPROC, VertexAttrib2d); +OPENGL_PROC(PFNGLVERTEXATTRIB2FVPROC, VertexAttrib2fv); +OPENGL_PROC(PFNGLVERTEXATTRIB2DVPROC, VertexAttrib2dv); +OPENGL_PROC(PFNGLVERTEXATTRIB3FPROC, VertexAttrib3f); +OPENGL_PROC(PFNGLVERTEXATTRIB3DPROC, VertexAttrib3d); +OPENGL_PROC(PFNGLVERTEXATTRIB3FVPROC, VertexAttrib3fv); +OPENGL_PROC(PFNGLVERTEXATTRIB3DVPROC, VertexAttrib3dv); +OPENGL_PROC(PFNGLVERTEXATTRIB4FPROC, VertexAttrib4f); +OPENGL_PROC(PFNGLVERTEXATTRIB4DPROC, VertexAttrib4d); +OPENGL_PROC(PFNGLVERTEXATTRIB4IVPROC, VertexAttrib4iv); +OPENGL_PROC(PFNGLVERTEXATTRIB4FVPROC, VertexAttrib4fv); +OPENGL_PROC(PFNGLVERTEXATTRIB4DVPROC, VertexAttrib4dv); +OPENGL_PROC(PFNGLVERTEXATTRIB4UIVPROC, VertexAttrib4uiv); + OPENGL_PROC(PFNGLUNIFORM1IPROC, Uniform1i); OPENGL_PROC(PFNGLUNIFORM1FPROC, Uniform1f); +OPENGL_PROC(PFNGLUNIFORM1DPROC, Uniform1d); OPENGL_PROC(PFNGLUNIFORM1UIPROC, Uniform1ui); OPENGL_PROC(PFNGLUNIFORM1IVPROC, Uniform1iv); OPENGL_PROC(PFNGLUNIFORM1FVPROC, Uniform1fv); +OPENGL_PROC(PFNGLUNIFORM1DVPROC, Uniform1dv); OPENGL_PROC(PFNGLUNIFORM1UIVPROC, Uniform1uiv); OPENGL_PROC(PFNGLUNIFORM2IPROC, Uniform2i); OPENGL_PROC(PFNGLUNIFORM2FPROC, Uniform2f); +OPENGL_PROC(PFNGLUNIFORM2DPROC, Uniform2d); OPENGL_PROC(PFNGLUNIFORM2UIPROC, Uniform2ui); OPENGL_PROC(PFNGLUNIFORM2IVPROC, Uniform2iv); OPENGL_PROC(PFNGLUNIFORM2FVPROC, Uniform2fv); +OPENGL_PROC(PFNGLUNIFORM2DVPROC, Uniform2dv); OPENGL_PROC(PFNGLUNIFORM2UIVPROC, Uniform2uiv); OPENGL_PROC(PFNGLUNIFORM3IPROC, Uniform3i); OPENGL_PROC(PFNGLUNIFORM3FPROC, Uniform3f); +OPENGL_PROC(PFNGLUNIFORM3DPROC, Uniform3d); OPENGL_PROC(PFNGLUNIFORM3UIPROC, Uniform3ui); OPENGL_PROC(PFNGLUNIFORM3IVPROC, Uniform3iv); OPENGL_PROC(PFNGLUNIFORM3FVPROC, Uniform3fv); +OPENGL_PROC(PFNGLUNIFORM3DVPROC, Uniform3dv); OPENGL_PROC(PFNGLUNIFORM3UIVPROC, Uniform3uiv); -OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4i); +OPENGL_PROC(PFNGLUNIFORM4IPROC, Uniform4i); OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4f); +OPENGL_PROC(PFNGLUNIFORM4DPROC, Uniform4d); OPENGL_PROC(PFNGLUNIFORM4UIPROC, Uniform4ui); OPENGL_PROC(PFNGLUNIFORM4IVPROC, Uniform4iv); OPENGL_PROC(PFNGLUNIFORM4FVPROC, Uniform4fv); +OPENGL_PROC(PFNGLUNIFORM4DVPROC, Uniform4dv); OPENGL_PROC(PFNGLUNIFORM4UIVPROC, Uniform4uiv); +OPENGL_PROC(PFNGLUNIFORMMATRIX2FVPROC, UniformMatrix2fv); +OPENGL_PROC(PFNGLUNIFORMMATRIX2DVPROC, UniformMatrix2dv); +OPENGL_PROC(PFNGLUNIFORMMATRIX3FVPROC, UniformMatrix3fv); +OPENGL_PROC(PFNGLUNIFORMMATRIX3DVPROC, UniformMatrix3dv); +OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv); +OPENGL_PROC(PFNGLUNIFORMMATRIX4DVPROC, UniformMatrix4dv); + OPENGL_PROC(PFNGLPROGRAMUNIFORM1IPROC, ProgramUniform1i); OPENGL_PROC(PFNGLPROGRAMUNIFORM1FPROC, ProgramUniform1f); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1DPROC, ProgramUniform1d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1UIPROC, ProgramUniform1ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1IVPROC, ProgramUniform1iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1FVPROC, ProgramUniform1fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1DVPROC, ProgramUniform1dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM1UIVPROC, ProgramUniform1uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2IPROC, ProgramUniform2i); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2FPROC, ProgramUniform2f); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2DPROC, ProgramUniform2d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2UIPROC, ProgramUniform2ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2IVPROC, ProgramUniform2iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2FVPROC, ProgramUniform2fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2DVPROC, ProgramUniform2dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM2UIVPROC, ProgramUniform2uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3IPROC, ProgramUniform3i); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3FPROC, ProgramUniform3f); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3DPROC, ProgramUniform3d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3UIPROC, ProgramUniform3ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3IVPROC, ProgramUniform3iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3FVPROC, ProgramUniform3fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3DVPROC, ProgramUniform3dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM3UIVPROC, ProgramUniform3uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4IPROC, ProgramUniform4i); OPENGL_PROC(PFNGLPROGRAMUNIFORM4FPROC, ProgramUniform4f); -OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4DPROC, ProgramUniform4d); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4UIPROC, ProgramUniform4ui); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4IVPROC, ProgramUniform4iv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4FVPROC, ProgramUniform4fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4DVPROC, ProgramUniform4dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORM4UIVPROC, ProgramUniform4uiv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX2FVPROC, ProgramUniformMatrix2fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX2DVPROC, ProgramUniformMatrix2dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX3FVPROC, ProgramUniformMatrix3fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX3DVPROC, ProgramUniformMatrix3dv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX4FVPROC, ProgramUniformMatrix4fv); +OPENGL_PROC(PFNGLPROGRAMUNIFORMMATRIX4DVPROC, ProgramUniformMatrix4dv); + OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram); -OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBoundsEXT, glDepthBoundsEXT); +OPENGL_PROC(PFNGLDEPTHBOUNDSEXTPROC, DepthBoundsEXT); OPENGL_PROC(PFNGLSTENCILOPSEPARATEPROC, StencilOpSeparate); OPENGL_PROC(PFNGLSTENCILFUNCSEPARATEPROC, StencilFuncSeparate); OPENGL_PROC(PFNGLSTENCILMASKSEPARATEPROC, StencilMaskSeparate); @@ -96,13 +153,25 @@ OPENGL_PROC(PFNGLFRAMEBUFFERTEXTURE3DPROC, FramebufferTexture3D); OPENGL_PROC(PFNGLFRAMEBUFFERRENDERBUFFERPROC, FramebufferRenderbuffer); OPENGL_PROC(PFNGLBLITFRAMEBUFFERPROC, BlitFramebuffer); OPENGL_PROC(PFNGLDRAWBUFFERSPROC, DrawBuffers); + +OPENGL_PROC(PFNGLENABLEIPROC, Enablei); +OPENGL_PROC(PFNGLDISABLEIPROC, Disablei); + OPENGL_PROC(PFNGLPRIMITIVERESTARTINDEXPROC, PrimitiveRestartIndex); +OPENGL_PROC(PFNGLGETINTEGER64VPROC, GetInteger64v); + +OPENGL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSPROC, CheckFramebufferStatus); + +//KHR_debug +OPENGL_PROC(PFNGLDEBUGMESSAGECONTROLARBPROC, DebugMessageControlARB); +OPENGL_PROC(PFNGLDEBUGMESSAGEINSERTARBPROC, DebugMessageInsertARB); +OPENGL_PROC(PFNGLDEBUGMESSAGECALLBACKARBPROC, DebugMessageCallbackARB); +//... + #ifndef __GNUG__ OPENGL_PROC(PFNGLBLENDCOLORPROC, BlendColor); OPENGL_PROC(PFNGLBLENDEQUATIONPROC, BlendEquation); OPENGL_PROC(PFNGLCOMPRESSEDTEXIMAGE2DPROC, CompressedTexImage2D); OPENGL_PROC(PFNGLACTIVETEXTUREPROC, ActiveTexture); - -OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT); #endif diff --git a/rpcs3/Emu/RSX/GL/GLProgram.cpp b/rpcs3/Emu/RSX/GL/GLProgram.cpp index b7f77177f7..033d1608b5 100644 --- a/rpcs3/Emu/RSX/GL/GLProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLProgram.cpp @@ -3,7 +3,7 @@ #include "Emu/Memory/Memory.h" #include "GLProgram.h" #include "GLGSRender.h" - +/* GLProgram::GLProgram() : id(0) { } @@ -116,3 +116,4 @@ void GLProgram::Delete() id = 0; m_locations.clear(); } +*/ \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/GLProgram.h b/rpcs3/Emu/RSX/GL/GLProgram.h index 076b3ce01f..024c05b8a1 100644 --- a/rpcs3/Emu/RSX/GL/GLProgram.h +++ b/rpcs3/Emu/RSX/GL/GLProgram.h @@ -1,7 +1,8 @@ #pragma once + #include "GLVertexProgram.h" #include "GLFragmentProgram.h" - +/* struct GLProgram { private: @@ -27,3 +28,4 @@ public: void SetVTex(u32 index); void Delete(); }; +*/ diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 0cb5972d14..a82547aeb7 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -7,7 +7,7 @@ struct GLTraits { typedef GLVertexProgram VertexProgramData; typedef GLFragmentProgram FragmentProgramData; - typedef GLProgram PipelineData; + typedef gl::glsl::program PipelineData; typedef void* PipelineProperties; typedef void* ExtraData; @@ -36,12 +36,18 @@ struct GLTraits static PipelineData *BuildProgram(VertexProgramData &vertexProgramData, FragmentProgramData &fragmentProgramData, const PipelineProperties &pipelineProperties, const ExtraData& extraData) { - GLProgram *result = new GLProgram(); - result->Create(vertexProgramData.id, fragmentProgramData.id); - //checkForGlError("m_program.Create"); - result->Use(); + PipelineData *result = new PipelineData(); + __glcheck result->create() + .attach(gl::glsl::shader_view(vertexProgramData.id)) + .attach(gl::glsl::shader_view(fragmentProgramData.id)) + .bind_fragment_data_location("ocol0", 0) + .bind_fragment_data_location("ocol1", 1) + .bind_fragment_data_location("ocol2", 2) + .bind_fragment_data_location("ocol3", 3) + .make(); + __glcheck result->use(); - LOG_NOTICE(RSX, "*** prog id = %d", result->id); + LOG_NOTICE(RSX, "*** prog id = %d", result->id()); LOG_NOTICE(RSX, "*** vp id = %d", vertexProgramData.id); LOG_NOTICE(RSX, "*** fp id = %d", fragmentProgramData.id); @@ -54,7 +60,7 @@ struct GLTraits static void DeleteProgram(PipelineData *ptr) { - ptr->Delete(); + ptr->remove(); } }; diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 10af89a112..ea69a65c3d 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -22,7 +22,7 @@ std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::stri void GLVertexDecompilerThread::insertHeader(std::stringstream &OS) { - OS << "#version 420" << std::endl << std::endl; + OS << "#version 140" << std::endl << std::endl; OS << "uniform mat4 scaleOffsetMat = mat4(1.0);" << std::endl; } @@ -31,7 +31,7 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v for (const ParamType PT : inputs) { for (const ParamItem &PI : PT.items) - OS << "layout(location = " << PI.location << ") in " << PT.type << " " << PI.name << ";" << std::endl; + OS << /*"layout(location = " << PI.location << ") "*/ "in " << PT.type << " " << PI.name << ";" << std::endl; } } diff --git a/rpcs3/Emu/RSX/GL/OpenGL.cpp b/rpcs3/Emu/RSX/GL/OpenGL.cpp index 7309fe1d7e..a4ef68af94 100644 --- a/rpcs3/Emu/RSX/GL/OpenGL.cpp +++ b/rpcs3/Emu/RSX/GL/OpenGL.cpp @@ -2,7 +2,7 @@ #include "Utilities/Log.h" #include "OpenGL.h" -void InitProcTable() +void gl::init() { #ifdef _WIN32 #define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n) diff --git a/rpcs3/Emu/RSX/GL/OpenGL.h b/rpcs3/Emu/RSX/GL/OpenGL.h index ce4612c66c..9f1ca10845 100644 --- a/rpcs3/Emu/RSX/GL/OpenGL.h +++ b/rpcs3/Emu/RSX/GL/OpenGL.h @@ -25,7 +25,10 @@ typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval); #include #endif -void InitProcTable(); +namespace gl +{ + void init(); +} struct OpenGL { diff --git a/rpcs3/Emu/RSX/GL/gl_helpers.cpp b/rpcs3/Emu/RSX/GL/gl_helpers.cpp new file mode 100644 index 0000000000..a670ccad83 --- /dev/null +++ b/rpcs3/Emu/RSX/GL/gl_helpers.cpp @@ -0,0 +1,470 @@ +#include "stdafx.h" +#include "gl_helpers.h" + +namespace gl +{ + const fbo screen{}; + + void fbo::create() + { + glGenFramebuffers(1, &m_id); + } + + void fbo::bind() const + { + glBindFramebuffer(GL_FRAMEBUFFER, m_id); + } + + void fbo::blit(const fbo& dst, areai src_area, areai dst_area, buffers buffers_, filter filter_) const + { + bind_as(target::read_frame_buffer); + dst.bind_as(target::draw_frame_buffer); + __glcheck glBlitFramebuffer( + src_area.x1, src_area.y1, src_area.x2, src_area.y2, + dst_area.x1, dst_area.y1, dst_area.x2, dst_area.y2, + (GLbitfield)buffers_, (GLenum)filter_); + } + + void fbo::bind_as(target target_) const + { + glBindFramebuffer((int)target_, id()); + } + + void fbo::remove() + { + glDeleteFramebuffers(1, &m_id); + m_id = 0; + } + + bool fbo::created() const + { + return m_id != 0; + } + + void fbo::check() const + { + save_binding_state save(*this); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) + { + throw std::logic_error(fmt::format("0x%04x", status)); + } + } + + void fbo::recreate() + { + if (created()) + remove(); + + create(); + } + + void fbo::draw_buffer(const attachment& buffer) const + { + save_binding_state save(*this); + GLenum buf = buffer.id(); + __glcheck glDrawBuffers(1, &buf); + } + + void fbo::draw_buffers(const std::initializer_list& indexes) const + { + save_binding_state save(*this); + std::vector ids; + ids.reserve(indexes.size()); + + for (auto &index : indexes) + ids.push_back(index.id()); + + __glcheck glDrawBuffers((GLsizei)ids.size(), ids.data()); + } + + void fbo::draw_arrays(draw_mode mode, GLsizei count, GLint first) const + { + save_binding_state save(*this); + __glcheck glDrawArrays((GLenum)mode, first, count); + } + + void fbo::draw_arrays(const buffer& buffer, draw_mode mode, GLsizei count, GLint first) const + { + buffer.bind(buffer::target::array); + draw_arrays(mode, count, first); + } + + void fbo::draw_arrays(const vao& buffer, draw_mode mode, GLsizei count, GLint first) const + { + buffer.bind(); + draw_arrays(mode, count, first); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const + { + save_binding_state save(*this); + __glcheck glDrawElements((GLenum)mode, count, (GLenum)type, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const + { + buffer.bind(buffer::target::array); + __glcheck glDrawElements((GLenum)mode, count, (GLenum)type, indices); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const + { + indices.bind(buffer::target::element_array); + __glcheck glDrawElements((GLenum)mode, count, (GLenum)type, (GLvoid*)indices_buffer_offset); + } + + void fbo::draw_elements(const buffer& buffer_, draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const + { + buffer_.bind(buffer::target::array); + draw_elements(mode, count, type, indices, indices_buffer_offset); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, const GLubyte *indices) const + { + draw_elements(mode, count, indices_type::ubyte, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLubyte *indices) const + { + draw_elements(buffer, mode, count, indices_type::ubyte, indices); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, const GLushort *indices) const + { + draw_elements(mode, count, indices_type::ushort, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLushort *indices) const + { + draw_elements(buffer, mode, count, indices_type::ushort, indices); + } + + void fbo::draw_elements(draw_mode mode, GLsizei count, const GLuint *indices) const + { + draw_elements(mode, count, indices_type::uint, indices); + } + + void fbo::draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLuint *indices) const + { + draw_elements(buffer, mode, count, indices_type::uint, indices); + } + + void fbo::clear(buffers buffers_) const + { + save_binding_state save(*this); + glClear((GLbitfield)buffers_); + } + + void fbo::clear(buffers buffers_, color4f color_value, double depth_value, u8 stencil_value) const + { + save_binding_state save(*this); + glClearColor(color_value.r, color_value.g, color_value.b, color_value.a); + glClearDepth(depth_value); + glClearStencil(stencil_value); + clear(buffers_); + } + + void fbo::copy_from(const void* pixels, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings) const + { + save_binding_state save(*this); + pixel_settings.apply(); + glDrawPixels(size.width, size.height, (GLenum)format_, (GLenum)type_, pixels); + } + + void fbo::copy_from(const buffer& buf, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings) const + { + save_binding_state save(*this); + buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf); + pixel_settings.apply(); + glDrawPixels(size.width, size.height, (GLenum)format_, (GLenum)type_, nullptr); + } + + void fbo::copy_to(void* pixels, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings) const + { + save_binding_state save(*this); + pixel_settings.apply(); + glReadPixels(coord.x, coord.y, coord.width, coord.height, (GLenum)format_, (GLenum)type_, pixels); + } + + void fbo::copy_to(const buffer& buf, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings) const + { + save_binding_state save(*this); + buffer::save_binding_state save_buffer(buffer::target::pixel_pack, buf); + pixel_settings.apply(); + glReadPixels(coord.x, coord.y, coord.width, coord.height, (GLenum)format_, (GLenum)type_, nullptr); + } + + fbo fbo::get_binded_draw_buffer() + { + GLint value; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &value); + + return{ (GLuint)value }; + } + + fbo fbo::get_binded_read_buffer() + { + GLint value; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &value); + + return{ (GLuint)value }; + } + + fbo fbo::get_binded_buffer() + { + GLint value; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value); + + return{ (GLuint)value }; + } + + GLuint fbo::id() const + { + return m_id; + } + + void fbo::set_id(GLuint id) + { + m_id = id; + } + + void texture::settings::apply(const texture &texture) const + { + save_binding_state save(texture); + + texture.pixel_unpack_settings().apply(); + + if (compressed_format(m_internal_format)) + { + int compressed_image_size = m_compressed_image_size; + if (!compressed_image_size) + { + switch (m_internal_format) + { + case texture::internal_format::compressed_rgb_s3tc_dxt1: + compressed_image_size = ((m_width + 2) / 3) * ((m_height + 2) / 3) * 6; + break; + + case texture::internal_format::compressed_rgba_s3tc_dxt1: + compressed_image_size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 8; + break; + + case texture::internal_format::compressed_rgba_s3tc_dxt3: + case texture::internal_format::compressed_rgba_s3tc_dxt5: + compressed_image_size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16; + break; + } + } + + __glcheck glCompressedTexImage2D((GLenum)m_parent->get_target(), m_level, (GLint)m_internal_format, m_width, m_height, 0, compressed_image_size, m_pixels); + } + else + { + __glcheck glTexImage2D((GLenum)m_parent->get_target(), m_level, (GLint)m_internal_format, m_width, m_height, 0, (GLint)m_format, (GLint)m_type, m_pixels); + } + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_LEVEL, m_max_level); + + if (m_pixels) + { + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_GENERATE_MIPMAP, m_generate_mipmap ? GL_TRUE : GL_FALSE); + } + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_S, (GLint)m_wrap_s); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_T, (GLint)m_wrap_t); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_R, (GLint)m_wrap_r); + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_COMPARE_MODE, (GLint)m_compare_mode); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_COMPARE_FUNC, (GLint)m_compare_func); + + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MIN_LOD, m_max_lod); + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_LOD, m_min_lod); + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_LOD_BIAS, m_lod); + + __glcheck glTexParameterfv((GLenum)m_parent->get_target(), GL_TEXTURE_BORDER_COLOR, m_border_color.rgba); + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MIN_FILTER, (GLint)m_min_filter); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MAG_FILTER, (GLint)m_mag_filter); + + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_R, (GLint)m_swizzle_r); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_G, (GLint)m_swizzle_g); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_B, (GLint)m_swizzle_b); + __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_A, (GLint)m_swizzle_a); + + __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_ANISOTROPY_EXT, m_aniso); + } + + void texture::settings::apply() + { + if (m_parent) + { + apply(*m_parent); + m_parent = nullptr; + } + } + + texture::settings& texture::settings::swizzle(texture::channel r, texture::channel g, texture::channel b, texture::channel a) + { + m_swizzle_r = r; + m_swizzle_g = g; + m_swizzle_b = b; + m_swizzle_a = a; + + return *this; + } + + texture::settings& texture::settings::format(texture::format format) + { + m_format = format; + return *this; + } + + texture::settings& texture::settings::type(texture::type type) + { + m_type = type; + return *this; + } + + texture::settings& texture::settings::internal_format(texture::internal_format format) + { + m_internal_format = format; + return *this; + } + + texture::settings& texture::settings::filter(min_filter min_filter, gl::filter mag_filter) + { + m_min_filter = min_filter; + m_mag_filter = mag_filter; + + return *this; + } + + texture::settings& texture::settings::width(uint width) + { + m_width = width; + return *this; + } + + texture::settings& texture::settings::height(uint height) + { + m_height = height; + return *this; + } + + texture::settings& texture::settings::size(sizei size) + { + return width(size.width).height(size.height); + } + + texture::settings& texture::settings::level(int value) + { + m_level = value; + return *this; + } + + texture::settings& texture::settings::compressed_image_size(int size) + { + m_compressed_image_size = size; + return *this; + } + + texture::settings& texture::settings::pixels(const void* pixels) + { + m_pixels = pixels; + return *this; + } + + texture::settings& texture::settings::aniso(float value) + { + m_aniso = value; + return *this; + } + + texture::settings& texture::settings::compare_mode(texture::compare_mode value) + { + m_compare_mode = value; + return *this; + } + texture::settings& texture::settings::compare_func(texture::compare_func value) + { + m_compare_func = value; + return *this; + } + texture::settings& texture::settings::compare(texture::compare_func func, texture::compare_mode mode) + { + return compare_func(func).compare_mode(mode); + } + + texture::settings& texture::settings::wrap_s(texture::wrap value) + { + m_wrap_s = value; + return *this; + } + texture::settings& texture::settings::wrap_t(texture::wrap value) + { + m_wrap_t = value; + return *this; + } + texture::settings& texture::settings::wrap_r(texture::wrap value) + { + m_wrap_r = value; + return *this; + } + texture::settings& texture::settings::wrap(texture::wrap s, texture::wrap t, texture::wrap r) + { + return wrap_s(s).wrap_t(t).wrap_r(r); + } + + texture::settings& texture::settings::max_lod(float value) + { + m_max_lod = value; + return *this; + } + texture::settings& texture::settings::min_lod(float value) + { + m_min_lod = value; + return *this; + } + texture::settings& texture::settings::lod(float value) + { + m_lod = value; + return *this; + } + texture::settings& texture::settings::max_level(int value) + { + m_max_level = value; + return *this; + } + texture::settings& texture::settings::generate_mipmap(bool value) + { + m_generate_mipmap = value; + return *this; + } + texture::settings& texture::settings::mipmap(int level, int max_level, float lod, float min_lod, float max_lod, bool generate) + { + return this->level(level).max_level(max_level).lod(lod).min_lod(min_lod).max_lod(max_lod).generate_mipmap(generate); + } + + texture::settings& texture::settings::border_color(color4f value) + { + m_border_color = value; + return *this; + } + + texture_view texture::with_level(int level) + { + return{ get_target(), id() }; + } + + texture::settings texture::config() + { + return{ this }; + } + + void texture::config(const settings& settings_) + { + settings_.apply(*this); + } +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/gl_helpers.h b/rpcs3/Emu/RSX/GL/gl_helpers.h new file mode 100644 index 0000000000..a63a873c88 --- /dev/null +++ b/rpcs3/Emu/RSX/GL/gl_helpers.h @@ -0,0 +1,2223 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Utilities/types.h" +#include "OpenGL.h" + +namespace gl +{ +#ifdef _DEBUG + struct __glcheck_impl_t + { + const char* file; + const char* function; + long line; + + constexpr __glcheck_impl_t(const char* file, const char* function, long line) + : file(file) + , function(function) + , line(line) + { + } + + ~__glcheck_impl_t() noexcept(false) + { + if (GLenum err = glGetError()) + { + std::string error; + switch (err) + { + case GL_INVALID_OPERATION: error = "invalid operation"; break; + case GL_INVALID_ENUM: error = "invalid enum"; break; + case GL_INVALID_VALUE: error = "invalid value"; break; + case GL_OUT_OF_MEMORY: error = "out of memory"; break; + case GL_INVALID_FRAMEBUFFER_OPERATION: error = "invalid framebuffer operation"; break; + default: error = "unknown error"; break; + } + + throw std::runtime_error(fmt::format("OpenGL error: %s. file '%s' function '%s' line %ld", error.c_str(), file, function, line)); + } + } + }; +#define __glcheck gl::__glcheck_impl_t{ __FILE__, __FUNCTION__, __LINE__ }, +#else +#define __glcheck +#endif + + class exception : public std::exception + { + protected: + std::string m_what; + + public: + const char* what() const noexcept override + { + return m_what.c_str(); + } + }; + + template + class save_binding_state_base + { + GLint m_last_binding; + + public: + save_binding_state_base(const Type& new_state) : save_binding_state_base() + { + new_state.bind(); + } + + save_binding_state_base() + { + glGetIntegerv(GetStateId, &m_last_binding); + } + + ~save_binding_state_base() + { + glBindBuffer(BindId, m_last_binding); + } + }; + + enum class filter + { + nearest = GL_NEAREST, + linear = GL_LINEAR + }; + + enum class min_filter + { + nearest = GL_NEAREST, + linear = GL_LINEAR, + nearest_mipmap_nearest = GL_NEAREST_MIPMAP_NEAREST, + nearest_mipmap_linear = GL_NEAREST_MIPMAP_LINEAR, + linear_mipmap_nearest = GL_LINEAR_MIPMAP_NEAREST, + linear_mipmap_linear = GL_LINEAR_MIPMAP_LINEAR + }; + + enum class buffers + { + none = 0, + color = GL_COLOR_BUFFER_BIT, + depth = GL_DEPTH_BUFFER_BIT, + stencil = GL_STENCIL_BUFFER_BIT, + + color_depth = color | depth, + color_depth_stencil = color | depth | stencil, + color_stencil = color | stencil, + + depth_stencil = depth | stencil + }; + + class pixel_pack_settings + { + bool m_swap_bytes = false; + bool m_lsb_first = false; + int m_row_length = 0; + int m_image_height = 0; + int m_skip_rows = 0; + int m_skip_pixels = 0; + int m_skip_images = 0; + int m_aligment = 4; + + public: + void apply() const + { + glPixelStorei(GL_PACK_SWAP_BYTES, m_swap_bytes ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_PACK_LSB_FIRST, m_lsb_first ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_PACK_ROW_LENGTH, m_row_length); + glPixelStorei(GL_PACK_IMAGE_HEIGHT, m_image_height); + glPixelStorei(GL_PACK_SKIP_ROWS, m_skip_rows); + glPixelStorei(GL_PACK_SKIP_PIXELS, m_skip_pixels); + glPixelStorei(GL_PACK_SKIP_IMAGES, m_skip_images); + glPixelStorei(GL_PACK_ALIGNMENT, m_aligment); + } + + pixel_pack_settings& swap_bytes(bool value = true) + { + m_swap_bytes = value; + return *this; + } + pixel_pack_settings& lsb_first(bool value = true) + { + m_lsb_first = value; + return *this; + } + pixel_pack_settings& row_length(int value) + { + m_row_length = value; + return *this; + } + pixel_pack_settings& image_height(int value) + { + m_image_height = value; + return *this; + } + pixel_pack_settings& skip_rows(int value) + { + m_skip_rows = value; + return *this; + } + pixel_pack_settings& skip_pixels(int value) + { + m_skip_pixels = value; + return *this; + } + pixel_pack_settings& skip_images(int value) + { + m_skip_images = value; + return *this; + } + pixel_pack_settings& aligment(int value) + { + m_aligment = value; + return *this; + } + }; + + class pixel_unpack_settings + { + bool m_swap_bytes = false; + bool m_lsb_first = false; + int m_row_length = 0; + int m_image_height = 0; + int m_skip_rows = 0; + int m_skip_pixels = 0; + int m_skip_images = 0; + int m_aligment = 4; + + public: + void apply() const + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, m_swap_bytes ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_UNPACK_LSB_FIRST, m_lsb_first ? GL_TRUE : GL_FALSE); + glPixelStorei(GL_UNPACK_ROW_LENGTH, m_row_length); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_image_height); + glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skip_rows); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skip_pixels); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_skip_images); + glPixelStorei(GL_UNPACK_ALIGNMENT, m_aligment); + } + + pixel_unpack_settings& swap_bytes(bool value = true) + { + m_swap_bytes = value; + return *this; + } + pixel_unpack_settings& lsb_first(bool value = true) + { + m_lsb_first = value; + return *this; + } + pixel_unpack_settings& row_length(int value) + { + m_row_length = value; + return *this; + } + pixel_unpack_settings& image_height(int value) + { + m_image_height = value; + return *this; + } + pixel_unpack_settings& skip_rows(int value) + { + m_skip_rows = value; + return *this; + } + pixel_unpack_settings& skip_pixels(int value) + { + m_skip_pixels = value; + return *this; + } + pixel_unpack_settings& skip_images(int value) + { + m_skip_images = value; + return *this; + } + pixel_unpack_settings& aligment(int value) + { + m_aligment = value; + return *this; + } + }; + + class vao; + + class buffer_pointer + { + public: + enum class type + { + s8 = GL_BYTE, + u8 = GL_UNSIGNED_BYTE, + s16 = GL_SHORT, + u16 = GL_UNSIGNED_SHORT, + s32 = GL_INT, + u32 = GL_UNSIGNED_INT, + f16 = GL_HALF_FLOAT, + f32 = GL_FLOAT, + f64 = GL_DOUBLE, + fixed = GL_FIXED, + s32_2_10_10_10_rev = GL_INT_2_10_10_10_REV, + u32_2_10_10_10_rev = GL_UNSIGNED_INT_2_10_10_10_REV, + u32_10f_11f_11f_rev = GL_UNSIGNED_INT_10F_11F_11F_REV + }; + + private: + vao* m_vao; + u32 m_offset; + u32 m_stride; + u32 m_size = 4; + type m_type = type::f32; + bool m_normalize = false; + + public: + buffer_pointer(vao* vao, u32 offset = 0, u32 stride = 0) + : m_vao(vao) + , m_offset(offset) + , m_stride(stride) + { + } + + const class ::gl::vao& get_vao() const + { + return *m_vao; + } + + class ::gl::vao& get_vao() + { + return *m_vao; + } + + buffer_pointer& offset(u32 value) + { + m_offset = value; + return *this; + } + + u32 offset() const + { + return m_offset; + } + + buffer_pointer& stride(u32 value) + { + m_stride = value; + return *this; + } + + u32 stride() const + { + return m_stride; + } + + buffer_pointer& size(u32 value) + { + m_size = value; + return *this; + } + + u32 size() const + { + return m_size; + } + + buffer_pointer& set_type(type value) + { + m_type = value; + return *this; + } + + type get_type() const + { + return m_type; + } + + buffer_pointer& normalize(bool value) + { + m_normalize = value; + return *this; + } + + bool normalize() const + { + return m_normalize; + } + + buffer_pointer& operator >> (u32 value) + { + return stride(value); + } + + buffer_pointer& config(type type_ = type::f32, u32 size_ = 4, bool normalize_ = false) + { + return set_type(type_).size(size_).normalize(normalize_); + } + }; + + class buffer + { + public: + enum class target + { + pixel_pack = GL_PIXEL_PACK_BUFFER, + pixel_unpack = GL_PIXEL_UNPACK_BUFFER, + array = GL_ARRAY_BUFFER, + element_array = GL_ELEMENT_ARRAY_BUFFER + }; + enum class access + { + read = GL_READ_ONLY, + write = GL_WRITE_ONLY, + read_write = GL_READ_WRITE + }; + + private: + GLuint m_id = GL_NONE; + target m_target = target::array; + + public: + buffer() = default; + + buffer(GLuint id) + { + set_id(id); + } + + ~buffer() + { + if (created()) + remove(); + } + + class save_binding_state + { + GLint m_last_binding; + GLenum m_target; + + public: + save_binding_state(target target_, const buffer& new_state) : save_binding_state(target_) + { + new_state.bind(target_); + } + + save_binding_state(target target_) + { + GLenum pname; + switch (target_) + { + case target::pixel_pack: pname = GL_PIXEL_PACK_BUFFER_BINDING; break; + case target::pixel_unpack: pname = GL_PIXEL_UNPACK_BUFFER_BINDING; break; + case target::array: pname = GL_ARRAY_BUFFER_BINDING; break; + case target::element_array: pname = GL_ELEMENT_ARRAY_BUFFER_BINDING; break; + } + + glGetIntegerv(pname, &m_last_binding); + m_target = (GLenum)target_; + } + + + ~save_binding_state() + { + glBindBuffer(m_target, m_last_binding); + } + }; + + void recreate() + { + if (created()) + { + remove(); + } + + create(); + } + + void recreate(GLsizeiptr size, const void* data = nullptr) + { + if (created()) + { + remove(); + } + + create(size, data); + } + + void create() + { + glGenBuffers(1, &m_id); + } + + void create(GLsizeiptr size, const void* data_ = nullptr) + { + create(); + data(size, data_); + } + + void data(GLsizeiptr size, const void* data_ = nullptr) + { + target target_ = current_target(); + save_binding_state save(target_, *this); + glBufferData((GLenum)target_, size, data_, GL_STREAM_COPY); + } + + void sub_data(GLintptr offset, GLsizeiptr size, const void* data_ = nullptr) + { + target target_ = current_target(); + save_binding_state save(target_, *this); + glBufferSubData((GLenum)target_, offset, size, data_); + } + + void bind(target target_) const + { + glBindBuffer((GLenum)target_, m_id); + } + + target current_target() const + { + return m_target; + } + + void remove() + { + glDeleteBuffers(1, &m_id); + m_id = 0; + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + + void map(std::function impl, access access_) + { + target target_ = current_target(); + save_binding_state save(target_, *this); + + if (GLubyte* ptr = (GLubyte*)glMapBuffer((GLenum)target_, (GLenum)access_)) + { + impl(ptr); + glUnmapBuffer((GLenum)target_); + } + } + + class mapper + { + buffer *m_parent; + GLubyte *m_data; + + public: + mapper(buffer& parent, access access_) + { + m_parent = &parent; + m_data = parent.map(access_); + } + + ~mapper() + { + m_parent->unmap(); + } + + GLubyte* get() const + { + return m_data; + } + }; + + GLubyte* map(access access_) + { + bind(current_target()); + + return (GLubyte*)glMapBuffer((GLenum)current_target(), (GLenum)access_); + } + + void unmap() + { + glUnmapBuffer((GLenum)current_target()); + } + }; + + class vao + { + template + class entry + { + vao& m_parent; + + public: + using save_binding_state = save_binding_state_base; + + entry(vao* parent) noexcept : m_parent(*parent) + { + } + + entry& operator = (const buffer& buf) noexcept + { + m_parent.bind(); + buf.bind(BindId); + + return *this; + } + }; + + GLuint m_id = GL_NONE; + + public: + entry pixel_pack_buffer{ this }; + entry pixel_unpack_buffer{ this }; + entry array_buffer{ this }; + entry element_array_buffer{ this }; + + vao() = default; + vao(vao&) = delete; + + vao(vao&& vao_) noexcept + { + swap(vao_); + } + vao(GLuint id) noexcept + { + set_id(id); + } + + ~vao() noexcept + { + if (created()) + remove(); + } + + void swap(vao& vao_) noexcept + { + auto my_old_id = id(); + set_id(vao_.id()); + vao_.set_id(my_old_id); + } + + vao& operator = (const vao& rhs) = delete; + vao& operator = (vao&& rhs) noexcept + { + swap(rhs); + return *this; + } + + void bind() const noexcept + { + glBindVertexArray(m_id); + } + + void create() noexcept + { + glGenVertexArrays(1, &m_id); + } + + void remove() noexcept + { + glDeleteVertexArrays(1, &m_id); + m_id = GL_NONE; + } + + uint id() const noexcept + { + return m_id; + } + + void set_id(uint id) noexcept + { + m_id = id; + } + + bool created() const noexcept + { + return m_id != GL_NONE; + } + + explicit operator bool() const noexcept + { + return created(); + } + + void enable_for_attributes(std::initializer_list indexes) noexcept + { + for (auto &index : indexes) + { + glEnableVertexAttribArray(index); + } + } + + void disable_for_attributes(std::initializer_list indexes) noexcept + { + for (auto &index : indexes) + { + glDisableVertexAttribArray(index); + } + } + + void enable_for_attribute(GLuint index) noexcept + { + enable_for_attributes({ index }); + } + + void disable_for_attribute(GLuint index) noexcept + { + disable_for_attributes({ index }); + } + + buffer_pointer operator + (u32 offset) const noexcept + { + return{ (vao*)this, offset }; + } + + buffer_pointer operator >> (u32 stride) const noexcept + { + return{ (vao*)this, {}, stride }; + } + + operator buffer_pointer() const noexcept + { + return{ (vao*)this }; + } + }; + + class texture_view; + class texture + { + GLuint m_id = 0; + GLuint m_level = 0; + class pixel_pack_settings m_pixel_pack_settings; + class pixel_unpack_settings m_pixel_unpack_settings; + + public: + enum class type + { + ubyte = GL_UNSIGNED_BYTE, + ushort = GL_UNSIGNED_SHORT, + uint = GL_UNSIGNED_INT, + + ubyte_3_3_2 = GL_UNSIGNED_BYTE_3_3_2, + ubyte_2_3_3_rev = GL_UNSIGNED_BYTE_2_3_3_REV, + + ushort_5_6_5 = GL_UNSIGNED_SHORT_5_6_5, + ushort_5_6_5_rev = GL_UNSIGNED_SHORT_5_6_5_REV, + ushort_4_4_4_4 = GL_UNSIGNED_SHORT_4_4_4_4, + ushort_4_4_4_4_rev = GL_UNSIGNED_SHORT_4_4_4_4_REV, + ushort_5_5_5_1 = GL_UNSIGNED_SHORT_5_5_5_1, + ushort_1_5_5_5_rev = GL_UNSIGNED_SHORT_1_5_5_5_REV, + + uint_8_8_8_8 = GL_UNSIGNED_INT_8_8_8_8, + uint_8_8_8_8_rev = GL_UNSIGNED_INT_8_8_8_8_REV, + uint_10_10_10_2 = GL_UNSIGNED_INT_10_10_10_2, + uint_2_10_10_10_rev = GL_UNSIGNED_INT_2_10_10_10_REV, + uint_24_8 = GL_UNSIGNED_INT_24_8, + + sbyte = GL_BYTE, + sshort = GL_SHORT, + sint = GL_INT, + f16 = GL_HALF_FLOAT, + f32 = GL_FLOAT, + f64 = GL_DOUBLE, + }; + + enum class channel + { + zero = GL_ZERO, + one = GL_ONE, + r = GL_RED, + g = GL_GREEN, + b = GL_BLUE, + a = GL_ALPHA, + }; + + enum class format + { + red = GL_RED, + r = GL_R, + rg = GL_RG, + rgb = GL_RGB, + rgba = GL_RGBA, + + bgr = GL_BGR, + bgra = GL_BGRA, + + stencil = GL_STENCIL_INDEX, + depth = GL_DEPTH_COMPONENT, + depth_stencil = GL_DEPTH_STENCIL + }; + + enum class internal_format + { + red = GL_RED, + r = GL_R, + rg = GL_RG, + rgb = GL_RGB, + rgba = GL_RGBA, + + bgr = GL_BGR, + bgra = GL_BGRA, + + stencil = GL_STENCIL_INDEX, + stencil8 = GL_STENCIL_INDEX8, + depth = GL_DEPTH_COMPONENT, + depth16 = GL_DEPTH_COMPONENT16, + depth_stencil = GL_DEPTH_STENCIL, + depth24_stencil8 = GL_DEPTH24_STENCIL8, + + compressed_rgb_s3tc_dxt1 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + compressed_rgba_s3tc_dxt1 = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + compressed_rgba_s3tc_dxt3 = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, + compressed_rgba_s3tc_dxt5 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT + }; + + enum class wrap + { + repeat = GL_REPEAT, + mirrored_repeat = GL_MIRRORED_REPEAT, + clamp_to_edge = GL_CLAMP_TO_EDGE, + clamp_to_border = GL_CLAMP_TO_BORDER, + mirror_clamp = GL_MIRROR_CLAMP_EXT, + //mirror_clamp_to_edge = GL_MIRROR_CLAMP_TO_EDGE, + mirror_clamp_to_border = GL_MIRROR_CLAMP_TO_BORDER_EXT + }; + + enum class compare_mode + { + none = GL_NONE, + ref_to_texture = GL_COMPARE_REF_TO_TEXTURE + }; + + enum class compare_func + { + never = GL_NEVER, + less = GL_LESS, + equal = GL_EQUAL, + lequal = GL_LEQUAL, + greater = GL_GREATER, + notequal = GL_NOTEQUAL, + gequal = GL_GEQUAL, + always = GL_ALWAYS + }; + + enum class target + { + texture1D = GL_TEXTURE_1D, + texture2D = GL_TEXTURE_2D, + texture3D = GL_TEXTURE_3D + }; + + enum class channel_type + { + none = GL_NONE, + signed_normalized = GL_SIGNED_NORMALIZED, + unsigned_normalized = GL_UNSIGNED_NORMALIZED, + float_ = GL_FLOAT, + int_ = GL_INT, + uint_ = GL_UNSIGNED_INT + }; + + enum class channel_name + { + red = GL_TEXTURE_RED_TYPE, + green = GL_TEXTURE_GREEN_TYPE, + blue = GL_TEXTURE_BLUE_TYPE, + alpha = GL_TEXTURE_ALPHA_TYPE, + depth = GL_TEXTURE_DEPTH_TYPE + }; + + class save_binding_state + { + GLint m_last_binding; + GLenum m_target; + + public: + save_binding_state(const texture& new_binding) noexcept + { + GLenum pname; + switch (new_binding.get_target()) + { + case target::texture1D: pname = GL_TEXTURE_1D_BINDING_EXT; break; + case target::texture2D: pname = GL_TEXTURE_2D_BINDING_EXT; break; + case target::texture3D: pname = GL_TEXTURE_3D_BINDING_EXT; break; + } + + glGetIntegerv(pname, &m_last_binding); + + new_binding.bind(); + m_target = (GLenum)new_binding.get_target(); + } + + ~save_binding_state() noexcept + { + glBindTexture(m_target, m_last_binding); + } + }; + + class settings; + + private: + target m_target = target::texture2D; + + public: + target get_target() const noexcept + { + return m_target; + } + + void set_target(target target) noexcept + { + m_target = target; + } + + static bool compressed_format(internal_format format_) noexcept + { + switch (format_) + { + case internal_format::compressed_rgb_s3tc_dxt1: + case internal_format::compressed_rgba_s3tc_dxt1: + case internal_format::compressed_rgba_s3tc_dxt3: + case internal_format::compressed_rgba_s3tc_dxt5: + return true; + } + + return false; + } + + uint id() const noexcept + { + return m_id; + } + + uint level() const noexcept + { + return m_level; + } + + void recreate() noexcept + { + if (created()) + remove(); + + create(); + } + + void recreate(target target_) noexcept + { + if (created()) + remove(); + + create(target_); + } + + void create() noexcept + { + glGenTextures(1, &m_id); + } + + void create(target target_) noexcept + { + set_target(target_); + create(); + } + + bool created() const noexcept + { + return m_id != 0; + } + + void remove() noexcept + { + glDeleteTextures(1, &m_id); + m_id = 0; + } + + void set_id(GLuint id) noexcept + { + m_id = id; + } + + void set_level(int level) noexcept + { + m_level = level; + } + + texture_view with_level(int level); + + explicit operator bool() const noexcept + { + return created(); + } + + void bind() const noexcept + { + glBindTexture((GLenum)get_target(), id()); + } + + settings config(); + + void config(const settings& settings_); + + class pixel_pack_settings& pixel_pack_settings() + { + return m_pixel_pack_settings; + } + + const class pixel_pack_settings& pixel_pack_settings() const + { + return m_pixel_pack_settings; + } + + class pixel_unpack_settings& pixel_unpack_settings() + { + return m_pixel_unpack_settings; + } + + const class pixel_unpack_settings& pixel_unpack_settings() const + { + return m_pixel_unpack_settings; + } + + int width() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_WIDTH, &result); + return (int)result; + } + + int height() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_HEIGHT, &result); + return (int)result; + } + + int depth() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_DEPTH, &result); + return (int)result; + } + + sizei size() const + { + return{ width(), height() }; + } + + size3i size3d() const + { + return{ width(), height(), depth() }; + } + + texture::format get_internal_format() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_INTERNAL_FORMAT, &result); + return (texture::format)result; + } + + texture::channel_type get_channel_type(texture::channel_name channel) const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), (GLenum)channel, &result); + return (texture::channel_type)result; + } + + int get_channel_count() const + { + int result = 0; + + if (get_channel_type(channel_name::red) != channel_type::none) + result++; + if (get_channel_type(channel_name::green) != channel_type::none) + result++; + if (get_channel_type(channel_name::blue) != channel_type::none) + result++; + if (get_channel_type(channel_name::alpha) != channel_type::none) + result++; + if (get_channel_type(channel_name::depth) != channel_type::none) + result++; + + return result; + } + + bool compressed() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_COMPRESSED, &result); + return result != 0; + } + + int compressed_size() const + { + save_binding_state save(*this); + GLint result; + glGetTexLevelParameteriv((GLenum)get_target(), level(), GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &result); + return (int)result; + } + + texture() = default; + texture(texture&) = delete; + + texture(texture&& texture_) + { + swap(texture_); + } + texture(target target_, GLuint id = 0) + { + m_target = target_; + set_id(id); + } + + ~texture() + { + if (created()) + remove(); + } + + void swap(texture& texture_) + { + auto my_old_id = id(); + auto my_old_target = get_target(); + set_id(texture_.id()); + set_target(texture_.get_target()); + texture_.set_id(my_old_id); + texture_.set_target(my_old_target); + } + + texture& operator = (const texture& rhs) = delete; + texture& operator = (texture&& rhs) + { + swap(rhs); + return *this; + } + + void copy_from(const void* src, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings) + { + save_binding_state save(*this); + pixel_settings.apply(); + __glcheck glTexSubImage2D((GLenum)get_target(), level(), 0, 0, width(), height(), (GLenum)format, (GLenum)type, src); + } + + void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings) + { + buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf); + copy_from(nullptr, format, type, pixel_settings); + } + + void copy_from(void* dst, texture::format format, texture::type type) + { + copy_from(dst, format, type, pixel_unpack_settings()); + } + + void copy_from(const buffer& buf, texture::format format, texture::type type) + { + copy_from(buf, format, type, pixel_unpack_settings()); + } + + void copy_to(void* dst, texture::format format, texture::type type, class pixel_pack_settings pixel_settings) const + { + save_binding_state save(*this); + pixel_settings.apply(); + __glcheck glGetTexImage((GLenum)get_target(), level(), (GLenum)format, (GLenum)type, dst); + } + + void copy_to(void* dst, texture::type type, class pixel_pack_settings pixel_settings) const + { + copy_to(dst, get_internal_format(), type, pixel_settings); + } + + void copy_to(const buffer& buf, texture::format format, texture::type type, class pixel_pack_settings pixel_settings) const + { + buffer::save_binding_state save_buffer(buffer::target::pixel_pack, buf); + copy_to(nullptr, format, type, pixel_settings); + } + + void copy_to(const buffer& buf, texture::type type, class pixel_pack_settings pixel_settings) const + { + buffer::save_binding_state save_buffer(buffer::target::pixel_pack, buf); + copy_to(nullptr, get_internal_format(), type, pixel_settings); + } + + void copy_to(void* dst, texture::format format, texture::type type) const + { + copy_to(dst, format, type, pixel_pack_settings()); + } + + void copy_to(void* dst, texture::type type) const + { + copy_to(dst, get_internal_format(), type, pixel_pack_settings()); + } + + void copy_to(const buffer& buf, texture::format format, texture::type type) const + { + copy_to(buf, format, type, pixel_pack_settings()); + } + + void copy_to(const buffer& buf, texture::type type) const + { + copy_to(buf, get_internal_format(), type, pixel_pack_settings()); + } + }; + + class rbo + { + GLuint m_id = 0; + + public: + rbo() = default; + + rbo(GLuint id) + { + set_id(id); + } + + ~rbo() + { + if (created()) + remove(); + } + + class save_binding_state + { + GLint m_old_value; + + public: + save_binding_state(const rbo& new_state) + { + glGetIntegerv(GL_RENDERBUFFER_BINDING, &m_old_value); + new_state.bind(); + } + + ~save_binding_state() + { + glBindRenderbuffer(GL_RENDERBUFFER, m_old_value); + } + }; + + void recreate() + { + if (created()) + remove(); + + create(); + } + + void recreate(texture::format format, u32 width, u32 height) + { + if (created()) + remove(); + + create(format, width, height); + } + + void create() + { + glGenRenderbuffers(1, &m_id); + } + + void create(texture::format format, u32 width, u32 height) + { + create(); + storage(format, width, height); + } + + void bind() const + { + glBindRenderbuffer(GL_RENDERBUFFER, m_id); + } + + void storage(texture::format format, u32 width, u32 height) + { + save_binding_state save(*this); + glRenderbufferStorage(GL_RENDERBUFFER, (GLenum)format, width, height); + } + + void remove() + { + glDeleteRenderbuffers(1, &m_id); + m_id = 0; + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + }; + + class texture::settings + { + texture *m_parent; + + texture::channel m_swizzle_r = texture::channel::r; + texture::channel m_swizzle_g = texture::channel::g; + texture::channel m_swizzle_b = texture::channel::b; + texture::channel m_swizzle_a = texture::channel::a; + + texture::format m_format = texture::format::rgba; + texture::internal_format m_internal_format = texture::internal_format::rgba; + texture::type m_type = texture::type::ubyte; + + gl::min_filter m_min_filter = gl::min_filter::nearest; + gl::filter m_mag_filter = gl::filter::nearest; + + uint m_width = 0; + uint m_height = 0; + int m_level = 0; + + int m_compressed_image_size = 0; + + const void* m_pixels = nullptr; + float m_aniso = 1.f; + texture::compare_mode m_compare_mode = texture::compare_mode::none; + texture::compare_func m_compare_func = texture::compare_func::greater; + + texture::wrap m_wrap_s = texture::wrap::repeat; + texture::wrap m_wrap_t = texture::wrap::repeat; + texture::wrap m_wrap_r = texture::wrap::repeat; + + float m_max_lod = 1000.f; + float m_min_lod = -1000.f; + float m_lod = 0.f; + int m_max_level = 1000; + bool m_generate_mipmap = false; + + color4f m_border_color; + + public: + settings(texture *parent = nullptr) : m_parent(parent) + { + } + + ~settings() + { + apply(); + } + + void apply(const texture &texture) const; + void apply(); + + settings& swizzle( + texture::channel r = texture::channel::r, + texture::channel g = texture::channel::g, + texture::channel b = texture::channel::b, + texture::channel a = texture::channel::a); + + settings& format(texture::format format); + settings& type(texture::type type); + settings& internal_format(texture::internal_format format); + settings& filter(min_filter min_filter, filter mag_filter); + settings& width(uint width); + settings& height(uint height); + settings& size(sizei size); + settings& level(int value); + settings& compressed_image_size(int size); + settings& pixels(const void* pixels); + settings& aniso(float value); + settings& compare_mode(texture::compare_mode value); + settings& compare_func(texture::compare_func value); + settings& compare(texture::compare_func func, texture::compare_mode mode); + + settings& wrap_s(texture::wrap value); + settings& wrap_t(texture::wrap value); + settings& wrap_r(texture::wrap value); + settings& wrap(texture::wrap s, texture::wrap t, texture::wrap r); + + settings& max_lod(float value); + settings& min_lod(float value); + settings& lod(float value); + settings& max_level(int value); + settings& generate_mipmap(bool value); + settings& mipmap(int level, int max_level, float lod, float min_lod, float max_lod, bool generate); + + settings& border_color(color4f value); + }; + + enum class draw_mode + { + points = GL_POINTS, + lines = GL_LINES, + line_loop = GL_LINE_LOOP, + line_strip = GL_LINE_STRIP, + triangles = GL_TRIANGLES, + triangle_strip = GL_TRIANGLE_STRIP, + triangle_fan = GL_TRIANGLE_FAN, + quads = GL_QUADS, + quad_strip = GL_QUAD_STRIP, + polygone = GL_POLYGON + }; + + enum class indices_type + { + ubyte = GL_UNSIGNED_BYTE, + ushort = GL_UNSIGNED_SHORT, + uint = GL_UNSIGNED_INT + }; + + class fbo + { + GLuint m_id = GL_NONE; + + public: + fbo() = default; + + fbo(GLuint id) + { + set_id(id); + } + + ~fbo() + { + if (created()) + remove(); + } + + class save_binding_state + { + GLint m_last_binding; + + public: + save_binding_state(const fbo& new_binding) + { + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_last_binding); + new_binding.bind(); + } + + ~save_binding_state() + { + glBindFramebuffer(GL_FRAMEBUFFER, m_last_binding); + } + }; + + class attachment + { + public: + enum class type + { + color = GL_COLOR_ATTACHMENT0, + depth = GL_DEPTH_ATTACHMENT, + stencil = GL_STENCIL_ATTACHMENT, + depth_stencil = GL_DEPTH_STENCIL_ATTACHMENT + }; + + protected: + GLuint m_id; + fbo &m_parent; + + public: + attachment(fbo& parent, type type) + : m_id((int)type) + , m_parent(parent) + { + } + + void set_id(uint id) + { + m_id = id; + } + + uint id() const + { + return m_id; + } + + void operator = (const rbo& rhs) + { + save_binding_state save(m_parent); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, m_id, GL_RENDERBUFFER, rhs.id()); + } + + void operator = (const texture& rhs) + { + save_binding_state save(m_parent); + + switch (rhs.get_target()) + { + case texture::target::texture1D: glFramebufferTexture1D(GL_FRAMEBUFFER, m_id, GL_TEXTURE_1D, rhs.id(), rhs.level()); break; + case texture::target::texture2D: glFramebufferTexture2D(GL_FRAMEBUFFER, m_id, GL_TEXTURE_2D, rhs.id(), rhs.level()); break; + case texture::target::texture3D: glFramebufferTexture3D(GL_FRAMEBUFFER, m_id, GL_TEXTURE_3D, rhs.id(), rhs.level(), 0); break; + } + } + }; + + class indexed_attachment : public attachment + { + public: + indexed_attachment(fbo& parent, type type) : attachment(parent, type) + { + } + + attachment operator[](int index) const + { + return{ m_parent, type(id() + index) }; + } + + std::vector range(int from, int count) const + { + std::vector result; + + for (int i = from; i < from + count; ++i) + result.push_back((*this)[i]); + + return result; + } + + using attachment::operator =; + }; + + indexed_attachment color{ *this, attachment::type::color }; + attachment depth{ *this, attachment::type::depth }; + attachment stencil{ *this, attachment::type::stencil }; + attachment depth_stencil{ *this, attachment::type::depth_stencil }; + + enum class target + { + read_frame_buffer = GL_READ_FRAMEBUFFER, + draw_frame_buffer = GL_DRAW_FRAMEBUFFER + }; + + void create(); + void bind() const; + void blit(const fbo& dst, areai src_area, areai dst_area, buffers buffers_ = buffers::color, filter filter_ = filter::nearest) const; + void bind_as(target target_) const; + void remove(); + bool created() const; + void check() const; + + void recreate(); + void draw_buffer(const attachment& buffer) const; + void draw_buffers(const std::initializer_list& indexes) const; + + void draw_arrays(draw_mode mode, GLsizei count, GLint first = 0) const; + void draw_arrays(const buffer& buffer, draw_mode mode, GLsizei count, GLint first = 0) const; + void draw_arrays(const vao& buffer, draw_mode mode, GLsizei count, GLint first = 0) const; + + void draw_elements(draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, indices_type type, const GLvoid *indices) const; + void draw_elements(draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const; + void draw_elements(const buffer& buffer_, draw_mode mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const; + void draw_elements(draw_mode mode, GLsizei count, const GLubyte *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLubyte *indices) const; + void draw_elements(draw_mode mode, GLsizei count, const GLushort *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLushort *indices) const; + void draw_elements(draw_mode mode, GLsizei count, const GLuint *indices) const; + void draw_elements(const buffer& buffer, draw_mode mode, GLsizei count, const GLuint *indices) const; + + void clear(buffers buffers_) const; + void clear(buffers buffers_, color4f color_value, double depth_value, u8 stencil_value) const; + + void copy_from(const void* pixels, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings = pixel_unpack_settings()) const; + void copy_from(const buffer& buf, sizei size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings = pixel_unpack_settings()) const; + + void copy_to(void* pixels, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings = pixel_pack_settings()) const; + void copy_to(const buffer& buf, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings = pixel_pack_settings()) const; + + static fbo get_binded_draw_buffer(); + static fbo get_binded_read_buffer(); + static fbo get_binded_buffer(); + + GLuint id() const; + void set_id(GLuint id); + + explicit operator bool() const + { + return created(); + } + }; + + extern const fbo screen; + + namespace glsl + { + class compilation_exception : public exception + { + public: + explicit compilation_exception(const std::string& what_arg) + { + m_what = "compilation failed: '" + what_arg + "'"; + } + }; + + class link_exception : public exception + { + public: + explicit link_exception(const std::string& what_arg) + { + m_what = "linkage failed: '" + what_arg + "'"; + } + }; + + class validation_exception : public exception + { + public: + explicit validation_exception(const std::string& what_arg) + { + m_what = "compilation failed: '" + what_arg + "'"; + } + }; + + class not_found_exception : public exception + { + public: + explicit not_found_exception(const std::string& what_arg) + { + m_what = what_arg + " not found."; + } + }; + + class shader + { + GLuint m_id = GL_NONE; + + public: + enum class type + { + fragment = GL_FRAGMENT_SHADER, + vertex = GL_VERTEX_SHADER, + geometry = GL_GEOMETRY_SHADER + }; + + shader() = default; + + shader(GLuint id) + { + set_id(id); + } + + shader(type type_) + { + create(type_); + } + + shader(type type_, const std::string& src) + { + create(type_); + source(src); + } + + ~shader() + { + if (created()) + remove(); + } + + void recreate(type type_) + { + if (created()) + remove(); + + create(type_); + } + + void create(type type_) + { + m_id = glCreateShader((GLenum)type_); + } + + void source(const std::string& src) const + { + const char* str = src.c_str(); + const GLint length = (GLint)src.length(); + + glShaderSource(m_id, 1, &str, &length); + } + + shader& compile() + { + glCompileShader(m_id); + + GLint status = GL_FALSE; + glGetShaderiv(m_id, GL_COMPILE_STATUS, &status); + + if (status == GL_FALSE) + { + GLint length = 0; + glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &length); + + std::string error_msg; + if (length) + { + std::unique_ptr buf(new char[length + 1]); + glGetShaderInfoLog(m_id, length, nullptr, buf.get()); + error_msg = buf.get(); + } + + throw compilation_exception(error_msg); + } + + return *this; + } + + void remove() + { + glDeleteShader(m_id); + m_id = 0; + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + }; + + class program + { + GLuint m_id = 0; + + public: + class uniform_t + { + program& m_program; + GLint m_location; + + public: + uniform_t(program& program, GLint location) + : m_program(program) + , m_location(location) + { + } + + GLint location() const + { + return m_location; + } + + void operator = (int rhs) const { m_program.use(); glUniform1i(location(), rhs); } + void operator = (float rhs) const { m_program.use(); glUniform1f(location(), rhs); } + //void operator = (double rhs) const { m_program.use(); glUniform1d(location(), rhs); } + + void operator = (const color1i& rhs) const { m_program.use(); glUniform1i(location(), rhs.r); } + void operator = (const color1f& rhs) const { m_program.use(); glUniform1f(location(), rhs.r); } + //void operator = (const color1d& rhs) const { m_program.use(); glUniform1d(location(), rhs.r); } + void operator = (const color2i& rhs) const { m_program.use(); glUniform2i(location(), rhs.r, rhs.g); } + void operator = (const color2f& rhs) const { m_program.use(); glUniform2f(location(), rhs.r, rhs.g); } + //void operator = (const color2d& rhs) const { m_program.use(); glUniform2d(location(), rhs.r, rhs.g); } + void operator = (const color3i& rhs) const { m_program.use(); glUniform3i(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color3f& rhs) const { m_program.use(); glUniform3f(location(), rhs.r, rhs.g, rhs.b); } + //void operator = (const color3d& rhs) const { m_program.use(); glUniform3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color4i& rhs) const { m_program.use(); glUniform4i(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const color4f& rhs) const { m_program.use(); glUniform4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + //void operator = (const color4d& rhs) const { m_program.use(); glUniform4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator = (const glm::ivec2& rhs) const { m_program.use(); glUniform2i(location(), rhs.r, rhs.g); } + void operator = (const glm::vec2& rhs) const { m_program.use(); glUniform2f(location(), rhs.r, rhs.g); } + //void operator = (const glm::dvec2& rhs) const { m_program.use(); glUniform2d(location(), rhs.r, rhs.g); } + void operator = (const glm::ivec3& rhs) const { m_program.use(); glUniform3i(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::vec3& rhs) const { m_program.use(); glUniform3f(location(), rhs.r, rhs.g, rhs.b); } + //void operator = (const glm::dvec3& rhs) const { m_program.use(); glUniform3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::ivec4& rhs) const { m_program.use(); glUniform4i(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const glm::vec4& rhs) const { m_program.use(); glUniform4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + //void operator = (const glm::dvec4& rhs) const { m_program.use(); glUniform4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator = (const glm::mat2& rhs) const { m_program.use(); glUniformMatrix2fv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + //void operator = (const glm::dmat2& rhs) const { m_program.use(); glUniformMatrix2dv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + void operator = (const glm::mat3& rhs) const { m_program.use(); glUniformMatrix3fv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + //void operator = (const glm::dmat3& rhs) const { m_program.use(); glUniformMatrix3dv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + void operator = (const glm::mat4& rhs) const { m_program.use(); glUniformMatrix4fv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + //void operator = (const glm::dmat4& rhs) const { m_program.use(); glUniformMatrix4dv(location(), 1, GL_FALSE, glm::value_ptr(rhs)); } + }; + + class attrib_t + { + GLuint m_program; + GLint m_location; + + public: + attrib_t(GLuint program, GLint location) + : m_program(program) + , m_location(location) + { + } + + GLint location() const + { + return m_location; + } + + void operator = (float rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1f(location(), rhs); } + void operator = (double rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1d(location(), rhs); } + + void operator = (const color1f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1f(location(), rhs.r); } + void operator = (const color1d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1d(location(), rhs.r); } + void operator = (const color2f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2f(location(), rhs.r, rhs.g); } + void operator = (const color2d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2d(location(), rhs.r, rhs.g); } + void operator = (const color3f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3f(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color3d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const color4f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const color4d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator = (const glm::vec2& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2f(location(), rhs.r, rhs.g); } + void operator = (const glm::dvec2& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2d(location(), rhs.r, rhs.g); } + void operator = (const glm::vec3& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3f(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::dvec3& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3d(location(), rhs.r, rhs.g, rhs.b); } + void operator = (const glm::vec4& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + void operator = (const glm::dvec4& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); } + + void operator =(buffer_pointer& pointer) const + { + pointer.get_vao().enable_for_attribute(location()); + glVertexAttribPointer(location(), pointer.size(), (GLenum)pointer.get_type(), pointer.normalize(), + pointer.stride(), (const void*)(size_t)pointer.offset()); + } + }; + + class uniforms_t + { + program& m_program; + std::unordered_map locations; + int active_texture = 0; + + public: + uniforms_t(program* program) : m_program(*program) + { + } + + void clear() + { + locations.clear(); + active_texture = 0; + } + + bool has_location(const std::string &name, int *location = nullptr) + { + int result = glGetUniformLocation(m_program.id(), name.c_str()); + + if (result < 0) + return false; + + locations[name] = result; + + if (location) + *location = result; + + return true; + } + + GLint location(const std::string &name) + { + auto finded = locations.find(name); + + if (finded != locations.end()) + { + return finded->second; + } + + int result = glGetUniformLocation(m_program.id(), name.c_str()); + + if (result < 0) + throw not_found_exception(name); + + locations[name] = result; + + return result; + } + + int texture(GLint location, int active_texture, const gl::texture& texture) + { + glActiveTexture(GL_TEXTURE0 + active_texture); + texture.bind(); + (*this)[location] = active_texture; + + return active_texture; + } + + int texture(const std::string &name, int active_texture, const gl::texture& texture_) + { + return texture(location(name), active_texture, texture_); + } + + int texture(const std::string &name, const gl::texture& texture_) + { + int atex; + auto finded = locations.find(name); + + if (finded != locations.end()) + { + atex = finded->second; + } + else + { + atex = active_texture++; + } + + return texture(name, atex, texture_); + } + + uniform_t operator[](GLint location) + { + return{ m_program, location }; + } + + uniform_t operator[](const std::string &name) + { + return{ m_program, location(name) }; + } + + void swap(uniforms_t& uniforms) + { + locations.swap(uniforms.locations); + std::swap(active_texture, uniforms.active_texture); + } + } uniforms{ this }; + + class attribs_t + { + program& m_program; + std::unordered_map m_locations; + + public: + attribs_t(program* program) : m_program(*program) + { + } + + GLint location(const std::string &name) + { + auto finded = m_locations.find(name); + + if (finded != m_locations.end()) + { + return finded->second; + } + + int result = glGetAttribLocation(m_program.id(), name.c_str()); + + if (result < 0) + throw not_found_exception(name); + + m_locations[name] = result; + + return result; + } + + attrib_t operator[](GLint location) + { + return{ m_program.id(), location }; + } + + attrib_t operator[](const std::string &name) + { + return{ m_program.id(), location(name) }; + } + + void swap(attribs_t& attribs) + { + m_locations.swap(attribs.m_locations); + } + } attribs{ this }; + + program& recreate() + { + if (created()) + remove(); + + return create(); + } + + program& create() + { + m_id = glCreateProgram(); + return *this; + } + + void remove() + { + glDeleteProgram(m_id); + m_id = 0; + uniforms.clear(); + } + + static program get_current_program() + { + GLint id; + glGetIntegerv(GL_CURRENT_PROGRAM, &id); + return{ (GLuint)id }; + } + + void use() + { + glUseProgram(m_id); + } + + void link() + { + glLinkProgram(m_id); + + GLint status = GL_FALSE; + glGetProgramiv(m_id, GL_LINK_STATUS, &status); + + if (status == GL_FALSE) + { + GLint length = 0; + glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length); + + std::string error_msg; + if (length) + { + std::unique_ptr buf(new char[length + 1]); + glGetProgramInfoLog(m_id, length, nullptr, buf.get()); + error_msg = buf.get(); + } + + throw link_exception(error_msg); + } + } + + void validate() + { + glValidateProgram(m_id); + + GLint status = GL_FALSE; + glGetProgramiv(m_id, GL_VALIDATE_STATUS, &status); + + if (status == GL_FALSE) + { + GLint length = 0; + glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length); + + std::string error_msg; + if (length) + { + std::unique_ptr buf(new char[length + 1]); + glGetProgramInfoLog(m_id, length, nullptr, buf.get()); + error_msg = buf.get(); + } + + throw validation_exception(error_msg); + } + } + + void make() + { + link(); + validate(); + } + + uint id() const + { + return m_id; + } + + void set_id(uint id) + { + uniforms.clear(); + m_id = id; + } + + bool created() const + { + return m_id != 0; + } + + explicit operator bool() const + { + return created(); + } + + program& attach(const shader& shader_) + { + glAttachShader(m_id, shader_.id()); + return *this; + } + + program& bind_attribute_location(const std::string& name, int index) + { + glBindAttribLocation(m_id, index, name.c_str()); + return *this; + } + + program& bind_fragment_data_location(const std::string& name, int color_number) + { + glBindFragDataLocation(m_id, color_number, name.c_str()); + return *this; + } + + int attribute_location(const std::string& name) + { + return glGetAttribLocation(m_id, name.c_str()); + } + + int uniform_location(const std::string& name) + { + return glGetUniformLocation(m_id, name.c_str()); + } + + program& operator += (const shader& rhs) + { + return attach(rhs); + } + + program& operator += (std::initializer_list shaders) + { + for (auto &shader : shaders) + *this += shader; + return *this; + } + + program() = default; + program(program&) = delete; + program(program&& program_) + { + swap(program_); + } + + program(GLuint id) + { + set_id(id); + } + + ~program() + { + if (created()) + remove(); + } + + void swap(program& program_) + { + auto my_old_id = id(); + set_id(program_.id()); + program_.set_id(my_old_id); + uniforms.swap(program_.uniforms); + attribs.swap(program_.attribs); + } + + program& operator = (const program& rhs) = delete; + program& operator = (program&& rhs) + { + swap(rhs); + return *this; + } + }; + + class shader_view : public shader + { + public: + shader_view(GLuint id) : shader(id) + { + } + + ~shader_view() + { + set_id(0); + } + }; + + class program_view : public program + { + public: + program_view(GLuint id) : program(id) + { + } + + ~program_view() + { + set_id(0); + } + }; + } + + class texture_view : public texture + { + public: + texture_view(texture::target target_, GLuint id) : texture(target_, id) + { + } + + ~texture_view() + { + set_id(0); + } + }; + + class fbo_view : public fbo + { + public: + fbo_view(GLuint id) : fbo(id) + { + } + + ~fbo_view() + { + set_id(0); + } + }; + + class rbo_view : public rbo + { + public: + rbo_view(GLuint id) : rbo(id) + { + } + + ~rbo_view() + { + set_id(0); + } + }; + + class buffer_view : public buffer + { + public: + buffer_view(GLuint id) : buffer(id) + { + } + + ~buffer_view() + { + set_id(0); + } + }; +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GSRender.cpp b/rpcs3/Emu/RSX/GSRender.cpp index 10e93e0646..58e2248c6b 100644 --- a/rpcs3/Emu/RSX/GSRender.cpp +++ b/rpcs3/Emu/RSX/GSRender.cpp @@ -5,9 +5,20 @@ #include "GSManager.h" #include "GSRender.h" + draw_context_t GSFrameBase::new_context() { - return std::shared_ptr(make_context(), [this](void* ctxt) { delete_context(ctxt); }); + if (void* context = make_context()) + { + return std::shared_ptr(context, [this](void* ctxt) { delete_context(ctxt); }); + } + + return nullptr; +} + +void GSFrameBase::title_message(const std::wstring& msg) +{ + m_title_message = msg; } GSRender::GSRender(frame_type type) : m_frame(Emu.GetCallbacks().get_gs_frame(type).release()) @@ -58,29 +69,4 @@ void GSRender::flip(int buffer) { if (m_frame) m_frame->flip(m_context); -} - - -GSLock::GSLock(GSRender& renderer, GSLockType type) - : m_renderer(renderer) - , m_type(type) -{ - switch (m_type) - { - case GS_LOCK_NOT_WAIT: m_renderer.cs_main.lock(); break; - case GS_LOCK_WAIT_FLIP: m_renderer.sem_flip.wait(); break; - } -} - -GSLock::~GSLock() -{ - switch (m_type) - { - case GS_LOCK_NOT_WAIT: m_renderer.cs_main.unlock(); break; - case GS_LOCK_WAIT_FLIP: m_renderer.sem_flip.try_post(); break; - } -} - -GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type) -{ -} +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GSRender.h b/rpcs3/Emu/RSX/GSRender.h index 35d3361ce6..c3c6acc5b3 100644 --- a/rpcs3/Emu/RSX/GSRender.h +++ b/rpcs3/Emu/RSX/GSRender.h @@ -1,5 +1,6 @@ #pragma once #include "Emu/RSX/RSXThread.h" +#include using draw_context_t = std::shared_ptr; @@ -21,6 +22,7 @@ public: virtual void set_current(draw_context_t ctx) = 0; virtual void flip(draw_context_t ctx) = 0; + virtual size2i client_size() = 0; virtual void* handle() const = 0; void title_message(const std::wstring&); @@ -53,26 +55,3 @@ public: void close(); void flip(int buffer) override; }; - -enum GSLockType -{ - GS_LOCK_NOT_WAIT, - GS_LOCK_WAIT_FLIP, -}; - -struct GSLock -{ -private: - GSRender& m_renderer; - GSLockType m_type; - -public: - GSLock(GSRender& renderer, GSLockType type); - - ~GSLock(); -}; - -struct GSLockCurrent : GSLock -{ - GSLockCurrent(GSLockType type); -}; \ No newline at end of file diff --git a/rpcs3/Emu/RSX/Null/NullGSRender.cpp b/rpcs3/Emu/RSX/Null/NullGSRender.cpp new file mode 100644 index 0000000000..efd06ae11f --- /dev/null +++ b/rpcs3/Emu/RSX/Null/NullGSRender.cpp @@ -0,0 +1,16 @@ +#include "stdafx.h" +#include "NullGSRender.h" +#include "Emu/System.h" + +NullGSRender::NullGSRender() : GSRender(frame_type::Null) +{ +} + +void NullGSRender::onexit_thread() +{ +} + +bool NullGSRender::domethod(u32 cmd, u32 value) +{ + return false; +} diff --git a/rpcs3/Emu/RSX/Null/NullGSRender.h b/rpcs3/Emu/RSX/Null/NullGSRender.h index 31e46bbe26..af1602a6c0 100644 --- a/rpcs3/Emu/RSX/Null/NullGSRender.h +++ b/rpcs3/Emu/RSX/Null/NullGSRender.h @@ -4,59 +4,9 @@ class NullGSRender final : public GSRender { public: - - NullGSRender() : GSRender(frame_type::Null) - { - } - - virtual ~NullGSRender() override - { - } + NullGSRender(); private: - virtual void oninit() override - { - } - - virtual void oninit_thread() override - { - } - - virtual void onexit_thread() override - { - } - - virtual void OnReset() override - { - } - - virtual bool domethod(u32, u32) override - { - return false; - } - - virtual void end() override - { - } - - virtual void flip(int buffer) override - { - } - - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override - { - } - - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override - { - } - - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override - { - } - - virtual void notifyProgramChange() override {} - virtual void notifyBlendStateChange() override {} - virtual void notifyDepthStencilStateChange() override {} - virtual void notifyRasterizerStateChange() override {} + void onexit_thread() override; + bool domethod(u32 cmd, u32 value) override; }; diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index c31a2d44f4..066ac3b363 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -18,7 +18,7 @@ namespace rsx // Address method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] = ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | - ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); + ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); // Control0 method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] = @@ -30,7 +30,7 @@ namespace rsx // Filter method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] = ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) - | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); + | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); // Image Rect method_registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); @@ -222,7 +222,7 @@ namespace rsx // Address method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] = ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | - ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); + ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); // Control0 method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] = @@ -234,7 +234,7 @@ namespace rsx // Filter method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] = ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) - | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); + | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); // Image Rect method_registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index f2a8342e98..014d862340 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -1,4 +1,5 @@ #pragma once +#include "Utilities/types.h" namespace rsx { @@ -127,4 +128,4 @@ namespace rsx //custom info u8 index() const; }; -} \ No newline at end of file +} diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index b38885013f..eacc8d4950 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -4,29 +4,32 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/RSX/GSManager.h" -#include "Emu/RSX/GSRender.h" -#include "Emu/SysCalls/Modules/cellVideoOut.h" #include "RSXThread.h" -#include "Utilities/types.h" #include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/CB_FUNC.h" +#include "Emu/SysCalls/lv2/sys_time.h" + +#include "Utilities/types.h" +#include + +using namespace std::chrono_literals; extern "C" { #include "libswscale/swscale.h" } -extern u64 get_system_time(); - -#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args.addr()) : args[x].value()) #define CMD_DEBUG 0 - +extern u64 get_system_time(); namespace rsx { + using rsx_method_t = void(*)(thread*, u32); + u32 method_registers[0x10000 >> 2]; + rsx_method_t methods[0x10000 >> 2]{}; template struct vertex_data_type_from_element_type; template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_F }; }; @@ -34,8 +37,47 @@ namespace rsx template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_UB }; }; template<> struct vertex_data_type_from_element_type { enum { type = CELL_GCM_VERTEX_S1 }; }; + namespace nv406e + { + force_inline void set_reference(thread* rsx, u32 arg) + { + rsx->ctrl->ref.exchange(arg); + } + + force_inline void semaphore_acquire(thread* rsx, u32 arg) + { + //TODO: dma + while (vm::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg) + { + if (Emu.IsStopped()) + break; + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } + + force_inline void semaphore_release(thread* rsx, u32 arg) + { + //TODO: dma + vm::write32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET], arg); + } + } + namespace nv4097 { + force_inline void texture_read_semaphore_release(thread* rsx, u32 arg) + { + //TODO: dma + vm::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], arg); + } + + force_inline void back_end_write_semaphore_release(thread* rsx, u32 arg) + { + //TODO: dma + vm::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], + (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff)); + } + //fire only when all data passed to rsx cmd buffer template force_inline void set_vertex_data_impl(thread* rsx, u32 arg) @@ -111,8 +153,563 @@ namespace rsx info.unpack(arg); info.array = info.size > 0; } + + force_inline void draw_arrays(thread* rsx, u32 arg) + { + u32 first = arg & 0xffffff; + u32 count = (arg >> 24) + 1; + + rsx->load_vertex_data(first, count); + } + + force_inline void draw_index_array(thread* rsx, u32 arg) + { + u32 first = arg & 0xffffff; + u32 count = (arg >> 24) + 1; + + rsx->load_vertex_data(first, count); + rsx->load_vertex_index_data(first, count); + } + + template + force_inline void set_transform_constant(thread* rsxthr, u32 arg) + { + u32& load = method_registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD]; + + static const size_t count = 4; + static const size_t size = count * sizeof(f32); + + memcpy(rsxthr->transform_constants[load++].rgba, method_registers + NV4097_SET_TRANSFORM_CONSTANT + index * count, size); + } + + template + force_inline void set_transform_program(thread* rsx, u32 arg) + { + u32& load = method_registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD]; + + static const size_t count = 4; + static const size_t size = count * sizeof(u32); + + memcpy(rsx->transform_program + load++ * count, method_registers + NV4097_SET_TRANSFORM_PROGRAM + index * count, size); + } + + force_inline void set_begin_end(thread* rsx, u32 arg) + { + if (arg) + { + rsx->begin(); + return; + } + + if (!rsx->vertex_draw_count) + { + bool has_array = false; + + for (int i = 0; i < rsx::limits::vertex_count; ++i) + { + if (rsx->vertex_arrays_info[i].array) + { + has_array = true; + break; + } + } + + if (!has_array) + { + u32 min_count = ~0; + + for (int i = 0; i < rsx::limits::vertex_count; ++i) + { + if (!rsx->vertex_arrays_info[i].size) + continue; + + u32 count = u32(rsx->vertex_arrays[i].size()) / + rsx::get_vertex_type_size(rsx->vertex_arrays_info[i].type) * rsx->vertex_arrays_info[i].size; + + if (count < min_count) + min_count = count; + } + + if (min_count && min_count < ~0) + { + rsx->vertex_draw_count = min_count; + } + } + } + + rsx->end(); + rsx->vertex_draw_count = 0; + } + + force_inline void get_report(thread* rsx, u32 arg) + { + u8 type = arg >> 24; + u32 offset = arg & 0xffffff; + + //TODO: use DMA + vm::ptr result = { rsx->local_mem_addr + offset }; + + result->timer = rsx->timestamp(); + + switch (type) + { + case CELL_GCM_ZPASS_PIXEL_CNT: + case CELL_GCM_ZCULL_STATS: + case CELL_GCM_ZCULL_STATS1: + case CELL_GCM_ZCULL_STATS2: + case CELL_GCM_ZCULL_STATS3: + result->value = 0; + LOG_WARNING(RSX, "NV4097_GET_REPORT: Unimplemented type %d", type); + break; + + default: + result->value = 0; + LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); + break; + } + + //result->padding = 0; + } + + force_inline void clear_report_value(thread* rsx, u32 arg) + { + switch (arg) + { + case CELL_GCM_ZPASS_PIXEL_CNT: + LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZPASS_PIXEL_CNT"); + break; + case CELL_GCM_ZCULL_STATS: + LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZCULL_STATS"); + break; + default: + LOG_ERROR(RSX, "NV4097_CLEAR_REPORT_VALUE: Bad type: %d", arg); + break; + } + } } + namespace nv308a + { + template + force_inline void color(u32 arg) + { + u32 point = method_registers[NV308A_POINT]; + u16 x = point; + u16 y = point >> 16; + + if (y) + { + LOG_ERROR(RSX, "%s: y is not null (0x%x)", __FUNCTION__, y); + } + + u32 address = get_address(method_registers[NV3062_SET_OFFSET_DESTIN] + (x << 2) + index * 4, method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]); + vm::write32(address, arg); + } + } + + namespace nv3089 + { + force_inline void image_in(u32 arg) + { + const u16 width = method_registers[NV3089_IMAGE_IN_SIZE]; + const u16 height = method_registers[NV3089_IMAGE_IN_SIZE] >> 16; + const u16 pitch = method_registers[NV3089_IMAGE_IN_FORMAT]; + const u8 origin = method_registers[NV3089_IMAGE_IN_FORMAT] >> 16; + const u8 inter = method_registers[NV3089_IMAGE_IN_FORMAT] >> 24; + + if (origin != 2 /* CELL_GCM_TRANSFER_ORIGIN_CORNER */) + { + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", origin); + } + + if (inter != 0 /* CELL_GCM_TRANSFER_INTERPOLATOR_ZOH */ && inter != 1 /* CELL_GCM_TRANSFER_INTERPOLATOR_FOH */) + { + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", inter); + } + + const u32 src_offset = method_registers[NV3089_IMAGE_IN_OFFSET]; + const u32 src_dma = method_registers[NV3089_SET_CONTEXT_DMA_IMAGE]; + + u32 dst_offset; + u32 dst_dma = 0; + + switch (method_registers[NV3089_SET_CONTEXT_SURFACE]) + { + case CELL_GCM_CONTEXT_SURFACE2D: + dst_dma = method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]; + dst_offset = method_registers[NV3062_SET_OFFSET_DESTIN]; + break; + + case CELL_GCM_CONTEXT_SWIZZLE2D: + dst_dma = method_registers[NV309E_SET_CONTEXT_DMA_IMAGE]; + dst_offset = method_registers[NV309E_SET_OFFSET]; + break; + + default: + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", method_registers[NV3089_SET_CONTEXT_SURFACE]); + break; + } + + if (!dst_dma) + return; + + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: src = 0x%x, dst = 0x%x", src_offset, dst_offset); + + const u16 u = arg; // inX (currently ignored) + const u16 v = arg >> 16; // inY (currently ignored) + + u8* pixels_src = vm::get_ptr(get_address(src_offset, src_dma)); + u8* pixels_dst = vm::get_ptr(get_address(dst_offset, dst_dma)); + + if (method_registers[NV3062_SET_COLOR_FORMAT] != 4 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 */ && + method_registers[NV3062_SET_COLOR_FORMAT] != 10 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8 */) + { + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_color_format (%d)", method_registers[NV3062_SET_COLOR_FORMAT]); + } + + const u32 in_bpp = method_registers[NV3062_SET_COLOR_FORMAT] == 4 ? 2 : 4; // bytes per pixel + const u32 out_bpp = method_registers[NV3089_SET_COLOR_FORMAT] == 7 ? 2 : 4; + + const s32 out_w = (s32)(u64(width) * (1 << 20) / method_registers[NV3089_DS_DX]); + const s32 out_h = (s32)(u64(height) * (1 << 20) / method_registers[NV3089_DT_DY]); + + if (method_registers[NV3089_SET_CONTEXT_SURFACE] == CELL_GCM_CONTEXT_SWIZZLE2D) + { + u8* linear_pixels = pixels_src; + u8* swizzled_pixels = new u8[in_bpp * width * height]; + + int sw_width = 1 << (int)log2(width); + int sw_height = 1 << (int)log2(height); + + for (int y = 0; y < sw_height; y++) + { + for (int x = 0; x < sw_width; x++) + { + switch (in_bpp) + { + case 1: + swizzled_pixels[linear_to_swizzle(x, y, 0, sw_width, sw_height, 0)] = linear_pixels[y * sw_height + x]; + break; + case 2: + ((u16*)swizzled_pixels)[linear_to_swizzle(x, y, 0, sw_width, sw_height, 0)] = ((u16*)linear_pixels)[y * sw_height + x]; + break; + case 4: + ((u32*)swizzled_pixels)[linear_to_swizzle(x, y, 0, sw_width, sw_height, 0)] = ((u32*)linear_pixels)[y * sw_height + x]; + break; + } + } + } + + pixels_src = swizzled_pixels; + } + + LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: w=%d, h=%d, pitch=%d, offset=0x%x, inX=%f, inY=%f, scaleX=%f, scaleY=%f", + width, height, pitch, src_offset, double(u) / 16, double(v) / 16, double(1 << 20) / (method_registers[NV3089_DS_DX]), + double(1 << 20) / (method_registers[NV3089_DT_DY])); + + std::unique_ptr temp; + + if (in_bpp != out_bpp && width != out_w && height != out_h) + { + // resize/convert if necessary + + temp.reset(new u8[out_bpp * out_w * out_h]); + + AVPixelFormat in_format = method_registers[NV3062_SET_COLOR_FORMAT] == 4 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? + AVPixelFormat out_format = method_registers[NV3089_SET_COLOR_FORMAT] == 7 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? + + std::unique_ptr sws(sws_getContext(width, height, in_format, out_w, out_h, out_format, + inter ? SWS_FAST_BILINEAR : SWS_POINT, NULL, NULL, NULL), sws_freeContext); + + int in_line = in_bpp * width; + u8* out_ptr = temp.get(); + int out_line = out_bpp * out_w; + + sws_scale(sws.get(), &pixels_src, &in_line, 0, height, &out_ptr, &out_line); + + pixels_src = temp.get(); // use resized image as a source + } + + if (method_registers[NV3089_CLIP_SIZE] != method_registers[NV3089_IMAGE_OUT_SIZE] || + method_registers[NV3089_IMAGE_OUT_SIZE] != (out_w | (out_h << 16)) || + method_registers[NV3089_IMAGE_OUT_POINT] || method_registers[NV3089_CLIP_POINT]) + { + // clip if necessary + + for (s32 y = method_registers[NV3089_CLIP_POINT] >> 16, dst_y = method_registers[NV3089_IMAGE_OUT_POINT] >> 16; y < out_h; y++, dst_y++) + { + if (dst_y >= 0 && dst_y < method_registers[NV3089_IMAGE_OUT_SIZE] >> 16) + { + // destination line + u8* dst_line = pixels_dst + dst_y * out_bpp * (method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff) + + std::min(std::max(method_registers[NV3089_IMAGE_OUT_POINT] & 0xffff, 0), method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff); + + size_t dst_max = std::min( + std::max((s32)(method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff) - (method_registers[NV3089_IMAGE_OUT_POINT] & 0xffff), 0), + method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff) * out_bpp; + + if (y >= 0 && y < std::min(method_registers[NV3089_CLIP_SIZE] >> 16, out_h)) + { + // source line + u8* src_line = pixels_src + y * out_bpp * out_w + + std::min(std::max(method_registers[NV3089_CLIP_POINT] & 0xffff, 0), method_registers[NV3089_CLIP_SIZE] & 0xffff); + size_t src_max = std::min( + std::max((s32)(method_registers[NV3089_CLIP_SIZE] & 0xffff) - (method_registers[NV3089_CLIP_POINT] & 0xffff), 0), + method_registers[NV3089_CLIP_SIZE] & 0xffff) * out_bpp; + + std::pair + z0 = { src_line + 0, std::min(dst_max, std::max(0, method_registers[NV3089_CLIP_POINT] & 0xffff)) }, + d0 = { src_line + z0.second, std::min(dst_max - z0.second, src_max) }, + z1 = { src_line + d0.second, dst_max - z0.second - d0.second }; + + memset(z0.first, 0, z0.second); + memcpy(d0.first, src_line, d0.second); + memset(z1.first, 0, z1.second); + } + else + { + memset(dst_line, 0, dst_max); + } + } + } + } + else + { + memcpy(pixels_dst, pixels_src, out_w * out_h * out_bpp); + } + + if (method_registers[NV3089_SET_CONTEXT_SURFACE] == CELL_GCM_CONTEXT_SWIZZLE2D) + { + delete[] pixels_src; + } + } + } + + namespace nv0039 + { + force_inline void buffer_notify(u32 arg) + { + const u32 inPitch = method_registers[NV0039_PITCH_IN]; + const u32 outPitch = method_registers[NV0039_PITCH_OUT]; + const u32 lineLength = method_registers[NV0039_LINE_LENGTH_IN]; + const u32 lineCount = method_registers[NV0039_LINE_COUNT]; + const u8 outFormat = method_registers[NV0039_FORMAT] >> 8; + const u8 inFormat = method_registers[NV0039_FORMAT]; + const u32 notify = arg; + + // The existing GCM commands use only the value 0x1 for inFormat and outFormat + if (inFormat != 0x01 || outFormat != 0x01) + { + LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", inFormat, outFormat); + } + + if (lineCount == 1 && !inPitch && !outPitch && !notify) + { + memcpy( + vm::get_ptr(get_address(method_registers[NV0039_OFFSET_OUT], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT])), + vm::get_ptr(get_address(method_registers[NV0039_OFFSET_IN], method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_IN])), + lineLength); + } + else + { + LOG_ERROR(RSX, "NV0039_OFFSET_IN: bad offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x", + method_registers[NV0039_OFFSET_IN], method_registers[NV0039_OFFSET_OUT], inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify); + } + } + } + + void flip_command(thread* rsx, u32 arg) + { + rsx->gcm_current_buffer = arg; + rsx->flip(arg); + + rsx->last_flip_time = get_system_time() - 1000000; + rsx->gcm_current_buffer = arg; + rsx->flip_status = 0; + + if (auto cb = rsx->flip_handler) + { + Emu.GetCallbackManager().Async([=](CPUThread& cpu) + { + cb(static_cast(cpu), 1); + }); + } + + rsx->sem_flip.post_and_wait(); + + //sync + double limit; + switch (Ini.GSFrameLimit.GetValue()) + { + case 1: limit = 50.; break; + case 2: limit = 59.94; break; + case 3: limit = 30.; break; + case 4: limit = 60.; break; + case 5: limit = rsx->fps_limit; break; //TODO + + case 0: + default: + return; + } + + std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - rsx->timer_sync.GetElapsedTimeInMilliSec()))); + rsx->timer_sync.Start(); + } + + struct __rsx_methods_t + { + using rsx_impl_method_t = void(*)(u32); + + template + force_inline static void call_impl_func(thread *rsx, u32 arg) + { + impl_func(rsx, arg); + } + + template + force_inline static void call_impl_func(thread *rsx, u32 arg) + { + impl_func(arg); + } + + template + static void wrapper(thread *rsx, u32 arg) + { + // try process using gpu + if (rsx->domethod(id, arg)) + return; + + // not handled by renderer + // try process using cpu + if (impl_func != nullptr) + call_impl_func(rsx, arg); + } + + /* + template class T, T impl_func = nullptr, int limit = 0> + static void bind_impl() + { + bind>(); + + if (id + step < limit) + bind_impl(); + } + + template class rsx_impl_method_t impl_func = nullptr> + static void bind() { bind_impl(); } + + template class rsx_method_t impl_func = nullptr> + static void bind() { bind_impl(); } + */ + + template + static void bind_impl() + { + if (methods[id]) + { + throw std::logic_error(fmt::format("redefinition rsx method implementation (0x%04x)", id)); + } + + methods[id] = wrapper; + } + + template + static void bind_cpu_only_impl() + { + if (methods[id]) + { + throw std::logic_error(fmt::format("redefinition rsx method implementation(cpu only) (0x%04x)", id)); + } + + methods[id] = call_impl_func; + } + + template static void bind() { bind_impl(); } + template static void bind() { bind_impl(); } + + //do not try process on gpu + template static void bind_cpu_only() { bind_cpu_only_impl(); } + //do not try process on gpu + template static void bind_cpu_only() { bind_cpu_only_impl(); } + +#define bind_2(index, offset, step, func) \ + bind>(); \ + bind>() + +#define bind_4(index, offset, step, func) \ + bind_2(index, offset, step, func); \ + bind_2(index + 2, offset + 2*step, step, func) + +#define bind_8(index, offset, step, func) \ + bind_4(index, offset, step, func); \ + bind_4(index + 4, offset + 4*step, step, func) + +#define bind_16(index, offset, step, func) \ + bind_8(index, offset, step, func); \ + bind_8(index + 8, offset + 8*step, step, func) + +#define bind_32(index, offset, step, func) \ + bind_16(index, offset, step, func); \ + bind_16(index + 16, offset + 16*step, step, func) + +#define bind_64(index, offset, step, func) \ + bind_32(index, offset, step, func); \ + bind_32(index + 32, offset + 32*step, step, func) + +#define bind_128(index, offset, step, func) \ + bind_64(index, offset, step, func); \ + bind_64(index + 64, offset + 64*step, step, func) + +#define bind_256(index, offset, step, func) \ + bind_128(index, offset, step, func); \ + bind_128(index + 128, offset + 128*step, step, func) + +#define bind_512(index, offset, step, func) \ + bind_256(index, offset, step, func); \ + bind_256(index + 256, offset + 256*step, step, func) + + __rsx_methods_t() + { + // NV406E + bind_cpu_only(); + bind(); + bind(); + + // NV4097 + bind(); + bind(); + bind(); + bind(); + bind(); + bind(); + //bind(); + bind_16(0, NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 1, nv4097::set_vertex_data_array_format); + bind_16(0, NV4097_SET_VERTEX_DATA4UB_M, 1, nv4097::set_vertex_data4ub_m); + bind_16(0, NV4097_SET_VERTEX_DATA1F_M, 1, nv4097::set_vertex_data1f_m); + bind_16(0, NV4097_SET_VERTEX_DATA2F_M + 1, 2, nv4097::set_vertex_data2f_m); + bind_16(0, NV4097_SET_VERTEX_DATA3F_M + 2, 3, nv4097::set_vertex_data3f_m); + bind_16(0, NV4097_SET_VERTEX_DATA4F_M + 3, 4, nv4097::set_vertex_data4f_m); + bind_16(0, NV4097_SET_VERTEX_DATA2S_M, 1, nv4097::set_vertex_data2s_m); + bind_16(0, NV4097_SET_VERTEX_DATA4S_M + 1, 2, nv4097::set_vertex_data4s_m); + bind_8(0, NV4097_SET_TRANSFORM_CONSTANT + 3, 4, nv4097::set_transform_constant); + bind_128(0, NV4097_SET_TRANSFORM_PROGRAM + 3, 4, nv4097::set_transform_program); + bind_cpu_only(); + bind_cpu_only(); + + //NV308A + bind_512(0, NV308A_COLOR, 1, nv308a::color); + + //NV3089 + bind(); + + //NV0039 + bind(); + + // custom methods + bind_cpu_only(); + } + } __rsx_methods; + u32 linear_to_swizzle(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth) { u32 offset = 0; @@ -204,1899 +801,119 @@ namespace rsx } } - -u32 thread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr) -{ - auto args = vm::ps3::ptr::make(args_addr); - std::string debug = GetMethodName(cmd); - debug += "("; - for (u32 i = 0; i < count; ++i) debug += (i ? ", " : "") + fmt::format("0x%x", ARGS(i)); - debug += ")"; - LOG_NOTICE(RSX, "OutOfArgsCount(x=%d, count=%d): %s", x, count, debug.c_str()); - - return 0; -} - -#define case_2(offset, step) \ - case offset: \ - case offset + step: -#define case_4(offset, step) \ - case_2(offset, step) \ - case_2(offset + 2*step, step) -#define case_8(offset, step) \ - case_4(offset, step) \ - case_4(offset + 4*step, step) -#define case_16(offset, step) \ - case_8(offset, step) \ - case_8(offset + 8*step, step) -#define case_32(offset, step) \ - case_16(offset, step) \ - case_16(offset + 16*step, step) -#define case_range(n, offset, step) \ - case_##n(offset, step) \ - index = (cmd - offset) / step - -void thread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count) -{ - auto args = vm::ps3::ptr::make(args_addr); - -#if CMD_DEBUG - std::string debug = GetMethodName(cmd); - debug += "("; - for (u32 i = 0; i < count; ++i) debug += (i ? ", " : "") + fmt::format("0x%x", ARGS(i)); - debug += ")"; - LOG_NOTICE(RSX, debug); -#endif - - u32 index = 0; - - m_used_gcm_commands.insert(cmd); - - switch (cmd) + void thread::load_vertex_data(u32 first, u32 count) { - // NV406E - case NV406E_SET_REFERENCE: - { - ctrl->ref.exchange(ARGS(0)); - break; - } + vertex_draw_count += count; - case NV406E_SET_CONTEXT_DMA_SEMAPHORE: - { - if (ARGS(0)) + for (int index = 0; index < limits::vertex_count; ++index) { - LOG_WARNING(RSX, "TODO: NV406E_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", ARGS(0)); - } - break; - } + auto &info = vertex_arrays_info[index]; - case NV4097_SET_SEMAPHORE_OFFSET: - { - m_PGRAPH_semaphore_offset = ARGS(0); - break; - } - - case NV406E_SEMAPHORE_OFFSET: - { - m_PFIFO_semaphore_offset = ARGS(0); - break; - } - - case NV406E_SEMAPHORE_ACQUIRE: - { - semaphorePFIFOAcquire(m_PFIFO_semaphore_offset, ARGS(0)); - break; - } - - case NV406E_SEMAPHORE_RELEASE: - { - m_PFIFO_semaphore_release_value = ARGS(0); - break; - } - - case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE: - { - semaphorePGRAPHTextureReadRelease(m_PGRAPH_semaphore_offset, ARGS(0)); - break; - } - - case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE: - { - u32 value = ARGS(0); - value = (value & 0xff00ff00) | ((value & 0xff) << 16) | ((value >> 16) & 0xff); - semaphorePGRAPHBackendRelease(m_PGRAPH_semaphore_offset, value); - break; - } - - // NV4097 - case 0x0003fead: - { - flip(0); - - last_flip_time = get_system_time(); - gcm_current_buffer = ARGS(0); - m_read_buffer = true; - flip_status = 0; - - if (auto cb = flip_handler) - { - Emu.GetCallbackManager().Async([=](CPUThread& cpu) + if (!info.array) // disabled or not a vertex array { - cb(static_cast(cpu), 1); - }); - } - - sem_flip.post_and_wait(); - - auto sync = [&]() - { - double limit; - switch (Ini.GSFrameLimit.GetValue()) - { - case 1: limit = 50.; break; - case 2: limit = 59.94; break; - case 3: limit = 30.; break; - case 4: limit = 60.; break; - case 5: limit = m_fps_limit; break; //TODO - - case 0: - default: - return; + continue; } - std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - timer_sync.GetElapsedTimeInMilliSec()))); - timer_sync.Start(); - }; + auto &data = vertex_arrays[index]; - sync(); - - //Emu.Pause(); - break; - } - - case NV4097_NO_OPERATION: - { - // Nothing to do here - break; - } - - case NV4097_SET_CONTEXT_DMA_REPORT: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_REPORT: 0x%x", ARGS(0)); - dma_report = ARGS(0); - } - break; - } - - case NV4097_NOTIFY: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_NOTIFY: 0x%x", ARGS(0)); - } - break; - } - - case NV4097_WAIT_FOR_IDLE: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_WAIT_FOR_IDLE: 0x%x", ARGS(0)); - } - break; - } - - case NV4097_PM_TRIGGER: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_PM_TRIGGER: 0x%x", ARGS(0)); - } - break; - } - - // Texture - case_range(16, NV4097_SET_TEXTURE_FORMAT, 0x20); - case_range(16, NV4097_SET_TEXTURE_OFFSET, 0x20); - case_range(16, NV4097_SET_TEXTURE_FILTER, 0x20); - case_range(16, NV4097_SET_TEXTURE_ADDRESS, 0x20); - case_range(16, NV4097_SET_TEXTURE_IMAGE_RECT, 32); - case_range(16, NV4097_SET_TEXTURE_BORDER_COLOR, 0x20); - case_range(16, NV4097_SET_TEXTURE_CONTROL0, 0x20); - case_range(16, NV4097_SET_TEXTURE_CONTROL1, 0x20); - { - // Done using methodRegisters in RSXTexture.cpp - break; - } - - case_range(16, NV4097_SET_TEX_COORD_CONTROL, 4); - { - const u32 a0 = ARGS(0); - u8 texMask2D = a0 & 1; - u8 texMaskCentroid = (a0 >> 4) & 1; - LOG_WARNING(RSX, "TODO: NV4097_SET_TEX_COORD_CONTROL(texMask2D=%d, texMaskCentroid=%d)", texMask2D, texMaskCentroid); - break; - } - - case_range(16, NV4097_SET_TEXTURE_CONTROL2, 4); - { - LOG_WARNING(RSX, "TODO: NV4097_SET_TEXTURE_CONTROL2"); - const u32 a0 = ARGS(0); - // TODO: Use these - u8 unknown = (a0 >> 8) & 0xFF; - u8 iso = (a0 >> 6) & 1; - u8 aniso = (a0 >> 7) & 1; - u8 slope = a0 & 0x1F; - break; - } - - case_range(16, NV4097_SET_TEXTURE_CONTROL3, 4); - { - rsx::texture& tex = textures[index]; - const u32 a0 = ARGS(0); - u32 pitch = a0 & 0xFFFFF; - u16 depth = a0 >> 20; - //tex.SetControl3(depth, pitch); - break; - } - - // Vertex Texture - case_range(4, NV4097_SET_VERTEX_TEXTURE_FORMAT, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_OFFSET, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_FILTER, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_ADDRESS, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR, 0x20); - case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL0, 0x20); - { - // Done using methodRegisters in RSXTexture.cpp - break; - } - - case_range(4, NV4097_SET_VERTEX_TEXTURE_CONTROL3, 0x20); - { - rsx::vertex_texture& tex = m_vertex_textures[index]; - const u32 a0 = ARGS(0); - u32 pitch = a0 & 0xFFFFF; - u16 depth = a0 >> 20; - //tex.SetControl3(depth, pitch); - break; - } - -#define bind_2(index, offset, step, func) \ - case offset : \ - func(this, ARGS(0)); \ - break; \ - case offset + step: \ - func(this, ARGS(0)); \ - break; - -#define bind_4(index, offset, step, func) \ - bind_2(index, offset, step, func); \ - bind_2(index + 2, offset + 2*step, step, func) - -#define bind_8(index, offset, step, func) \ - bind_4(index, offset, step, func); \ - bind_4(index + 4, offset + 4*step, step, func) - -#define bind_16(index, offset, step, func) \ - bind_8(index, offset, step, func); \ - bind_8(index + 8, offset + 8*step, step, func) - -#define bind_32(index, offset, step, func) \ - bind_16(index, offset, step, func); \ - bind_16(index + 16, offset + 16*step, step, func) - -#define bind_64(index, offset, step, func) \ - bind_32(index, offset, step, func); \ - bind_32(index + 32, offset + 32*step, step, func) - -#define bind_128(index, offset, step, func) \ - bind_64(index, offset, step, func); \ - bind_64(index + 64, offset + 64*step, step, func) - -#define bind_256(index, offset, step, func) \ - bind_128(index, offset, step, func); \ - bind_128(index + 128, offset + 128*step, step, func) - -#define bind_512(index, offset, step, func) \ - bind_256(index, offset, step, func); \ - bind_256(index + 256, offset + 256*step, step, func) - - // Vertex data - bind_16(0, NV4097_SET_VERTEX_DATA4UB_M, 4, rsx::nv4097::set_vertex_data4ub_m); - bind_16(0, NV4097_SET_VERTEX_DATA2F_M, 8, rsx::nv4097::set_vertex_data2f_m); - bind_16(0, NV4097_SET_VERTEX_DATA4F_M, 16, rsx::nv4097::set_vertex_data4f_m); - - case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 4); - break; - - case_range(16, NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 4); - { - const u32 a0 = ARGS(0); - - rsx::data_array_format_info &cv = vertex_arrays_info[index]; - cv.unpack(a0); - cv.array = cv.size > 0; - - break; - } - - // Vertex Attribute - case NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: - { - if (u32 mask = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_VERTEX_ATTRIB_INPUT_MASK: 0x%x", mask); - } - - //VertexData[0].prog.attributeInputMask = ARGS(0); - break; - } - - case NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: - { - if (u32 mask = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK: 0x%x", mask); - } - - //VertexData[0].prog.attributeOutputMask = ARGS(0); - //FragmentData.prog.attributeInputMask = ARGS(0)/* & ~0x20*/; - break; - } - - // Color Mask - case NV4097_SET_COLOR_MASK: - notifyRasterizerStateChange(); - break; - - case NV4097_SET_COLOR_MASK_MRT: - { - if (u32 mask = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_COLOR_MASK_MRT: 0x%x", mask); - } - break; - } - - // Alpha testing - case NV4097_SET_ALPHA_TEST_ENABLE: - break; - - case NV4097_SET_ALPHA_FUNC: - break; - - case NV4097_SET_ALPHA_REF: - break; - - // Cull face - case NV4097_SET_CULL_FACE_ENABLE: - notifyRasterizerStateChange(); - break; - - case NV4097_SET_CULL_FACE: - notifyRasterizerStateChange(); - break; - - // Front face - case NV4097_SET_FRONT_FACE: - notifyRasterizerStateChange(); - break; - - // Blending - case NV4097_SET_BLEND_ENABLE: - notifyBlendStateChange(); - break; - - case NV4097_SET_BLEND_ENABLE_MRT: - notifyBlendStateChange(); - break; - - case NV4097_SET_BLEND_FUNC_SFACTOR: - notifyBlendStateChange(); - break; - - case NV4097_SET_BLEND_FUNC_DFACTOR: - notifyBlendStateChange(); - break; - - case NV4097_SET_BLEND_COLOR: - notifyBlendStateChange(); - break; - - case NV4097_SET_BLEND_COLOR2: - break; - - case NV4097_SET_BLEND_EQUATION: - notifyBlendStateChange(); - break; - case NV4097_SET_REDUCE_DST_COLOR: - break; - - // Depth bound testing - case NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE: - { - m_set_depth_bounds_test = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_DEPTH_BOUNDS_MIN: - { - m_set_depth_bounds = true; - const u32 a0 = ARGS(0); - m_depth_bounds_min = (float&)a0; - - if (count == 2) - { - const u32 a1 = ARGS(1); - m_depth_bounds_max = (float&)a1; - } - break; - } - - case NV4097_SET_DEPTH_BOUNDS_MAX: - { - m_set_depth_bounds = true; - const u32 a0 = ARGS(0); - m_depth_bounds_max = (float&)a0; - break; - } - - // Viewport - case NV4097_SET_VIEWPORT_HORIZONTAL: - break; - - case NV4097_SET_VIEWPORT_VERTICAL: - break; - - case NV4097_SET_VIEWPORT_SCALE: - case NV4097_SET_VIEWPORT_OFFSET: - { - // Done in Vertex Shader - break; - } - - // Clipping - case NV4097_SET_CLIP_MIN: - { - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - - m_set_clip = true; - m_clip_min = (float&)a0; - m_clip_max = (float&)a1; - - //LOG_NOTICE(RSX, "NV4097_SET_CLIP_MIN: clip_min=%.01f, clip_max=%.01f", m_clip_min, m_clip_max); - break; - } - - case NV4097_SET_CLIP_MAX: - { - const u32 a0 = ARGS(0); - - m_set_clip = true; - m_clip_max = (float&)a0; - - //LOG_NOTICE(RSX, "NV4097_SET_CLIP_MAX: clip_max=%.01f", m_clip_max); - break; - } - - // Depth testing - case NV4097_SET_DEPTH_TEST_ENABLE: - break; - - case NV4097_SET_DEPTH_FUNC: - notifyDepthStencilStateChange(); - break; - - case NV4097_SET_DEPTH_MASK: - notifyDepthStencilStateChange(); - break; - - // Polygon mode/offset - case NV4097_SET_FRONT_POLYGON_MODE: - { - m_set_front_polygon_mode = true; - m_front_polygon_mode = ARGS(0); - break; - } - - case NV4097_SET_BACK_POLYGON_MODE: - { - m_set_back_polygon_mode = true; - m_back_polygon_mode = ARGS(0); - break; - } - - case NV4097_SET_POLY_OFFSET_FILL_ENABLE: - { - m_set_poly_offset_fill = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLY_OFFSET_LINE_ENABLE: - { - m_set_poly_offset_line = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLY_OFFSET_POINT_ENABLE: - { - m_set_poly_offset_point = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR: - { - //m_set_depth_test = true; - m_set_poly_offset_mode = true; - - const u32 a0 = ARGS(0); - m_poly_offset_scale_factor = (float&)a0; - - if (count == 2) - { - const u32 a1 = ARGS(1); - m_poly_offset_bias = (float&)a1; - } - break; - } - - case NV4097_SET_POLYGON_OFFSET_BIAS: - { - //m_set_depth_test = true; - m_set_poly_offset_mode = true; - - const u32 a0 = ARGS(0); - m_poly_offset_bias = (float&)a0; - break; - } - - case NV4097_SET_CYLINDRICAL_WRAP: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CYLINDRICAL_WRAP: 0x%x", ARGS(0)); - } - break; - } - - // Clearing - case NV4097_CLEAR_ZCULL_SURFACE: - break; - case NV4097_CLEAR_SURFACE: - { - const u32 a0 = ARGS(0); - domethod(NV4097_CLEAR_SURFACE, a0); - break; - } - case NV4097_SET_ZSTENCIL_CLEAR_VALUE: - break; - case NV4097_SET_COLOR_CLEAR_VALUE: - break; - - case NV4097_SET_CLEAR_RECT_HORIZONTAL: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CLEAR_RECT_HORIZONTAL: 0x%x", value); - } - break; - } - - case NV4097_SET_CLEAR_RECT_VERTICAL: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CLEAR_RECT_VERTICAL: 0x%x", value); - } - break; - } - - // Arrays - case NV4097_INLINE_ARRAY: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_INLINE_ARRAY: 0x%x", value); - } - break; - } - - case NV4097_DRAW_ARRAYS: - { - for (u32 c = 0; c> 24) + 1; - - //LOG_WARNING(RSX, "NV4097_DRAW_ARRAYS: %d - %d", first, _count); - - if (first < draw_array_first) + if (info.frequency) { - draw_array_first = first; + LOG_ERROR(RSX, "%s: frequency is not null (%d, index=%d)", __FUNCTION__, info.frequency, index); } - draw_array_count += _count; - } - break; - } + u32 offset = method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index]; + u32 address = get_address(offset & 0x7fffffff, offset >> 31); - case NV4097_SET_INDEX_ARRAY_ADDRESS: - { - m_indexed_array.m_addr = rsx::get_address(ARGS(0), ARGS(1) & 0xf); - m_indexed_array.m_type = ARGS(1) >> 4; - break; - } + u32 type_size = get_vertex_type_size(info.type); + u32 element_size = type_size * info.size; - case NV4097_DRAW_INDEX_ARRAY: - { - for (u32 c=0; c> 24) + 1; + u32 dst_position = (u32)data.size(); + data.resize(dst_position + count * element_size); - if (first < m_indexed_array.m_first) m_indexed_array.m_first = first; + u32 base_offset = method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; + u32 base_index = method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; - int pos = (int)m_indexed_array.m_data.size(); - - switch (m_indexed_array.m_type) + for (u32 i = 0; i < count; ++i) { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - m_indexed_array.m_data.resize(pos + 4 * _count); - break; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - m_indexed_array.m_data.resize(pos + 2 * _count); - break; - } + auto src = vm::get_ptr(address + base_offset + info.stride * (first + i + base_index)); + u8* dst = data.data() + dst_position + i * element_size; - for (u32 i=first; i< first + _count; ++i) - { - u32 index; - switch(m_indexed_array.m_type) + switch (type_size) { - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: - index = vm::ps3::read32(m_indexed_array.m_addr + i * 4); - *(u32*)&m_indexed_array.m_data[i * 4] = index; + case 1: + memcpy(dst, src, info.size); break; - case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: - index = vm::ps3::read16(m_indexed_array.m_addr + i * 2); - *(u16*)&m_indexed_array.m_data[i * 2] = index; + case 2: + { + auto* c_src = (const be_t*)src; + u16* c_dst = (u16*)dst; + + for (u32 j = 0; j < info.size; ++j) + { + *c_dst++ = *c_src++; + } break; } - if (index < m_indexed_array.index_min) m_indexed_array.index_min = index; - if (index > m_indexed_array.index_max) m_indexed_array.index_max = index; - } + case 4: + { + auto* c_src = (const be_t*)src; + u32* c_dst = (u32*)dst; - m_indexed_array.m_count += _count; - } - break; - } - - case NV4097_SET_VERTEX_DATA_BASE_OFFSET: - break; - - case NV4097_SET_VERTEX_DATA_BASE_INDEX: - { - m_vertex_data_base_index = ARGS(0); - break; - } - - case NV4097_SET_BEGIN_END: - { - const u32 a0 = ARGS(0); - - //LOG_WARNING(RSX, "NV4097_SET_BEGIN_END: 0x%x", a0); - - if (!m_indexed_array.m_count && !draw_array_count) - { - u32 min_vertex_size = ~0; - for (unsigned id = 0; id < rsx::limits::vertex_count; id++) - { - auto &i = vertex_arrays_info[id]; - if (!i.size) - continue; - - u32 vertex_size = vertex_arrays[id].size() / (i.size * rsx::get_vertex_type_size(i.type)); - - if (min_vertex_size > vertex_size) - min_vertex_size = vertex_size; - } - - draw_array_count = min_vertex_size; - draw_array_first = 0; - } - - m_read_buffer = Ini.GSReadColorBuffer.GetValue() || (!m_indexed_array.m_count && !draw_array_count); - - if (a0) - { - begin(a0); - } - else - { - end(); - } - break; - } - - // Shader - case NV4097_SET_SHADER_PROGRAM: - notifyProgramChange(); - break; - - case NV4097_SET_SHADER_CONTROL: - { - m_shader_ctrl = ARGS(0); - break; - } - - case NV4097_SET_SHADE_MODE: - { - m_set_shade_mode = true; - m_shade_mode = ARGS(0); - break; - } - - case NV4097_SET_SHADER_PACKER: - { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_SHADER_PACKER: 0x%x", ARGS(0)); - } - } - - case NV4097_SET_SHADER_WINDOW: - { - const u32 a0 = ARGS(0); - m_shader_window_height = a0 & 0xfff; - m_shader_window_origin = (a0 >> 12) & 0xf; - m_shader_window_pixel_centers = a0 >> 16; - break; - } - - // Transform - case NV4097_SET_TRANSFORM_PROGRAM_LOAD: - { - //LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: prog = %d", ARGS(0)); - - m_cur_vertex_prog = &m_vertex_progs[ARGS(0)]; - m_cur_vertex_prog->data.clear(); - - if (count == 2) - { - const u32 start = ARGS(1); - if (start) - { - LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start); + for (u32 j = 0; j < info.size; ++j) + { + *c_dst++ = *c_src++; + } + break; + } + } } } - notifyProgramChange(); - break; } - case NV4097_SET_TRANSFORM_PROGRAM_START: + void thread::load_vertex_index_data(u32 first, u32 count) { - const u32 start = ARGS(0); - if (start) - { - LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_START: start = %d", start); - } - break; - } + u32 address = get_address(method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf); + u32 type = method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4; - case_range(32, NV4097_SET_TRANSFORM_PROGRAM, 4); - { - //LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM[%d](%d)", index, count); + u32 type_size = type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 ? sizeof(u32) : sizeof(u16); + u32 dst_offset = (u32)vertex_index_array.size(); + vertex_index_array.resize(dst_offset + count * type_size); - if (!m_cur_vertex_prog) - { - LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_PROGRAM: m_cur_vertex_prog is null"); - break; - } - - for (u32 i = 0; i < count; ++i) - { - m_cur_vertex_prog->data.push_back(ARGS(i)); - } - notifyProgramChange(); - break; - } - - case NV4097_SET_TRANSFORM_TIMEOUT: - { - // TODO: - // (cmd)[1] = CELL_GCM_ENDIAN_SWAP((count) | ((registerCount) << 16)); \ - - if (!m_cur_vertex_prog) - { - LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_TIMEOUT: m_cur_vertex_prog is null"); - break; - } - - //m_cur_vertex_prog->Decompile(); - break; - } - - case NV4097_SET_TRANSFORM_BRANCH_BITS: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_TRANSFORM_BRANCH_BITS: 0x%x", value); - } - break; - } - - case NV4097_SET_TRANSFORM_CONSTANT_LOAD: - { - if ((count - 1) % 4) - { - LOG_ERROR(RSX, "NV4097_SET_TRANSFORM_CONSTANT_LOAD: bad count %d", count); - break; - } - - for (u32 id = ARGS(0), i = 1; i> 16; - - if (count == 2) - { - m_set_scissor_vertical = true; - m_scissor_y = ARGS(1) & 0xffff; - m_scissor_h = ARGS(1) >> 16; - } - break; - } - - case NV4097_SET_SCISSOR_VERTICAL: - { - m_set_scissor_vertical = true; - m_scissor_y = ARGS(0) & 0xffff; - m_scissor_h = ARGS(0) >> 16; - break; - } - - // Depth/Color buffer usage - case NV4097_SET_SURFACE_FORMAT: - { - auto buffers = vm::get_ptr(m_gcm_buffers_addr); - m_width = buffers[gcm_current_buffer].width; - m_height = buffers[gcm_current_buffer].height; - - CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum(Ini.GSResolution.GetValue())]; - m_width_scale = (float)res.width / m_width * 2.0f; - m_height_scale = (float)res.height / m_height * 2.0f; - m_width = (u32)res.width; - m_height = (u32)res.height; - break; - } - - case NV4097_SET_SURFACE_COLOR_TARGET: - break; - - case NV4097_SET_SURFACE_COLOR_AOFFSET: - break; - - case NV4097_SET_SURFACE_COLOR_BOFFSET: - break; - - case NV4097_SET_SURFACE_COLOR_COFFSET: - break; - - case NV4097_SET_SURFACE_COLOR_DOFFSET: - break; - - case NV4097_SET_SURFACE_ZETA_OFFSET: - break; - - case NV4097_SET_SURFACE_PITCH_A: - break; - - case NV4097_SET_SURFACE_PITCH_B: - break; - - case NV4097_SET_SURFACE_PITCH_C: - break; - - case NV4097_SET_SURFACE_PITCH_D: - break; - - case NV4097_SET_SURFACE_PITCH_Z: - break; - - case NV4097_SET_CONTEXT_DMA_COLOR_A: - break; - - case NV4097_SET_CONTEXT_DMA_COLOR_B: - break; - - case NV4097_SET_CONTEXT_DMA_COLOR_C: - break; - - case NV4097_SET_CONTEXT_DMA_COLOR_D: - break; - - case NV4097_SET_CONTEXT_DMA_ZETA: - break; - - case NV4097_SET_CONTEXT_DMA_SEMAPHORE: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_SEMAPHORE: 0x%x", value); - } - break; - } - - case NV4097_SET_CONTEXT_DMA_NOTIFIES: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_CONTEXT_DMA_NOTIFIES: 0x%x", value); - } - break; - } - - case NV4097_SET_SURFACE_CLIP_HORIZONTAL: - break; - - case NV4097_SET_SURFACE_CLIP_VERTICAL: - break; - - // Anti-aliasing - case NV4097_SET_ANTI_ALIASING_CONTROL: - { - const u32 a0 = ARGS(0); - - const u8 enable = a0 & 0xf; - const u8 alphaToCoverage = (a0 >> 4) & 0xf; - const u8 alphaToOne = (a0 >> 8) & 0xf; - const u16 sampleMask = a0 >> 16; - - if (a0) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ANTI_ALIASING_CONTROL: 0x%x", a0); - } - break; - } - - // Line/Polygon smoothing - case NV4097_SET_LINE_SMOOTH_ENABLE: - { - m_set_line_smooth = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLY_SMOOTH_ENABLE: - { - m_set_poly_smooth = ARGS(0) ? true : false; - break; - } - - // Line width - case NV4097_SET_LINE_WIDTH: - { - m_set_line_width = true; - const u32 a0 = ARGS(0); - m_line_width = (float)a0 / 8.0f; - break; - } - - // Line/Polygon stipple - case NV4097_SET_LINE_STIPPLE: - { - m_set_line_stipple = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_LINE_STIPPLE_PATTERN: - { - m_set_line_stipple = true; - const u32 a0 = ARGS(0); - m_line_stipple_factor = a0 & 0xffff; - m_line_stipple_pattern = a0 >> 16; - break; - } - - case NV4097_SET_POLYGON_STIPPLE: - { - m_set_polygon_stipple = ARGS(0) ? true : false; - break; - } - - case NV4097_SET_POLYGON_STIPPLE_PATTERN: - { - for (u32 i = 0; i < 32; i++) - { - m_polygon_stipple_pattern[i] = ARGS(i); - } - break; - } - - // Zcull - case NV4097_SET_ZCULL_EN: - notifyDepthStencilStateChange(); - break; - - case NV4097_SET_ZCULL_CONTROL0: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_CONTROL0: 0x%x", value); - } - break; - } - - case NV4097_SET_ZCULL_CONTROL1: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_CONTROL1: 0x%x", value); - } - break; - } - - case NV4097_SET_ZCULL_STATS_ENABLE: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_SET_ZCULL_STATS_ENABLE: 0x%x", value); - } - break; - } - - case NV4097_ZCULL_SYNC: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV4097_ZCULL_SYNC: 0x%x", value); - } - break; - } - - // Reports - case NV4097_GET_REPORT: - { - const u32 a0 = ARGS(0); - u8 type = a0 >> 24; - u32 offset = a0 & 0xffffff; - - u32 value; - switch(type) - { - case CELL_GCM_ZPASS_PIXEL_CNT: - case CELL_GCM_ZCULL_STATS: - case CELL_GCM_ZCULL_STATS1: - case CELL_GCM_ZCULL_STATS2: - case CELL_GCM_ZCULL_STATS3: - value = 0; - LOG_WARNING(RSX, "NV4097_GET_REPORT: Unimplemented type %d", type); - break; - - default: - value = 0; - LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); - break; - } - - // Get timestamp, and convert it from microseconds to nanoseconds - u64 timestamp = get_system_time() * 1000; - - // NOTE: DMA broken, implement proper lpar mapping (sys_rsx) - //dma_write64(dma_report, offset + 0x0, timestamp); - //dma_write32(dma_report, offset + 0x8, value); - //dma_write32(dma_report, offset + 0xc, 0); - - vm::ps3::write64(local_mem_addr + offset + 0x0, timestamp); - vm::ps3::write32(local_mem_addr + offset + 0x8, value); - vm::ps3::write32(local_mem_addr + offset + 0xc, 0); - break; - } - - case NV4097_CLEAR_REPORT_VALUE: - { - const u32 type = ARGS(0); + u32 base_offset = method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; + u32 base_index = method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; switch (type) { - case CELL_GCM_ZPASS_PIXEL_CNT: - LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZPASS_PIXEL_CNT"); + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: + for (u32 i = 0; i < count; ++i) + { + (u32&)vertex_index_array[dst_offset + i * sizeof(u32)] = vm::read32(address + (first + i) * sizeof(u32)); + } break; - case CELL_GCM_ZCULL_STATS: - LOG_WARNING(RSX, "TODO: NV4097_CLEAR_REPORT_VALUE: ZCULL_STATS"); - break; - default: - LOG_ERROR(RSX, "NV4097_CLEAR_REPORT_VALUE: Bad type: %d", type); + + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: + for (u32 i = 0; i < count; ++i) + { + (u16&)vertex_index_array[dst_offset + i * sizeof(u16)] = vm::read16(address + (first + i) * sizeof(u16)); + } break; } - break; } - // Clip Plane - case NV4097_SET_USER_CLIP_PLANE_CONTROL: + void thread::begin() { - const u32 a0 = ARGS(0); - m_set_clip_plane = true; - m_clip_plane_0 = (a0 & 0xf) ? true : false; - m_clip_plane_1 = ((a0 >> 4)) & 0xf ? true : false; - m_clip_plane_2 = ((a0 >> 8)) & 0xf ? true : false; - m_clip_plane_3 = ((a0 >> 12)) & 0xf ? true : false; - m_clip_plane_4 = ((a0 >> 16)) & 0xf ? true : false; - m_clip_plane_5 = (a0 >> 20) ? true : false; - break; - } - - // Fog - case NV4097_SET_FOG_MODE: - { - m_set_fog_mode = true; - m_fog_mode = ARGS(0); - break; - } - - case NV4097_SET_FOG_PARAMS: - { - m_set_fog_params = true; - const u32 a0 = ARGS(0); - const u32 a1 = ARGS(1); - m_fog_param0 = (float&)a0; - m_fog_param1 = (float&)a1; - break; - } - - // Zmin_max - case NV4097_SET_ZMIN_MAX_CONTROL: - { - const u8 cullNearFarEnable = ARGS(0) & 0xf; - const u8 zclampEnable = (ARGS(0) >> 4) & 0xf; - const u8 cullIgnoreW = (ARGS(0) >> 8) & 0xf; - - LOG_WARNING(RSX, "TODO: NV4097_SET_ZMIN_MAX_CONTROL: cullNearFarEnable=%d, zclampEnable=%d, cullIgnoreW=%d", cullNearFarEnable, zclampEnable, cullIgnoreW); - break; - } - - case NV4097_SET_WINDOW_OFFSET: - { - const u16 x = ARGS(0); - const u16 y = ARGS(0) >> 16; - - LOG_WARNING(RSX, "TODO: NV4097_SET_WINDOW_OFFSET: x=%d, y=%d", x, y); - break; - } - - case NV4097_SET_FREQUENCY_DIVIDER_OPERATION: - { - m_set_frequency_divider_operation = ARGS(0); - - LOG_WARNING(RSX, "TODO: NV4097_SET_FREQUENCY_DIVIDER_OPERATION: %d", m_set_frequency_divider_operation); - break; - } - - case NV4097_SET_RENDER_ENABLE: - { - const u32 offset = ARGS(0) & 0xffffff; - const u8 mode = ARGS(0) >> 24; - - LOG_WARNING(RSX, "TODO: NV4097_SET_RENDER_ENABLE: Offset=0x%06x, Mode=0x%x", offset, mode); - break; - } - - case NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE: - { - const u32 enable = ARGS(0); - - LOG_WARNING(RSX, "TODO: NV4097_SET_ZPASS_PIXEL_COUNT_ENABLE: %d", enable); - break; - } - - // NV0039 - case NV0039_SET_CONTEXT_DMA_BUFFER_IN: - { - const u32 srcContext = ARGS(0); - const u32 dstContext = ARGS(1); - m_context_dma_buffer_in_src = srcContext; - m_context_dma_buffer_in_dst = dstContext; - break; - } - - case NV0039_OFFSET_IN: - { - const u32 inOffset = ARGS(0); - const u32 outOffset = ARGS(1); - const u32 inPitch = ARGS(2); - const u32 outPitch = ARGS(3); - const u32 lineLength = ARGS(4); - const u32 lineCount = ARGS(5); - const u8 outFormat = (ARGS(6) >> 8); - const u8 inFormat = (ARGS(6) >> 0); - const u32 notify = ARGS(7); - - // The existing GCM commands use only the value 0x1 for inFormat and outFormat - if (inFormat != 0x01 || outFormat != 0x01) - { - LOG_ERROR(RSX, "NV0039_OFFSET_IN: Unsupported format: inFormat=%d, outFormat=%d", inFormat, outFormat); - } - - if (lineCount == 1 && !inPitch && !outPitch && !notify) - { - memcpy(vm::get_ptr(rsx::get_address(outOffset, 0)), vm::get_ptr(rsx::get_address(inOffset, 0)), lineLength); - } - else - { - LOG_ERROR(RSX, "NV0039_OFFSET_IN: bad offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x", - inOffset, outOffset, inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify); - } - break; - } - - case NV0039_OFFSET_OUT: // [E : RSXThread]: TODO: unknown/illegal method [0x00002310](0x0) - { - const u32 offset = ARGS(0); - - if (!offset) - { - } - else - { - LOG_ERROR(RSX, "TODO: NV0039_OFFSET_OUT: offset=0x%x", offset); - } - break; - } - - case NV0039_PITCH_IN: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV0039_PITCH_IN: 0x%x", value); - } - break; - } - - case NV0039_BUFFER_NOTIFY: - { - if (u32 value = ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV0039_BUFFER_NOTIFY: 0x%x", value); - } - break; - } - - // NV3062 - case NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN: - { - if (count == 1) - { - m_context_dma_img_dst = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV3062_SET_CONTEXT_DMA_IMAGE__DESTIN: unknown arg count (%d)", count); - } - break; - } - - case NV3062_SET_OFFSET_DESTIN: - { - if (count == 1) - { - m_dst_offset = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV3062_SET_OFFSET_DESTIN: unknown arg count (%d)", count); - } - break; - } - - case NV3062_SET_COLOR_FORMAT: - { - if (count == 2 || count == 4) - { - m_color_format = ARGS(0); - m_color_format_src_pitch = ARGS(1); - m_color_format_dst_pitch = ARGS(1) >> 16; - - if (count == 4) - { - if (ARGS(2)) - { - LOG_ERROR(RSX, "NV3062_SET_COLOR_FORMAT: unknown arg2 value (0x%x)", ARGS(2)); - } - - m_dst_offset = ARGS(3); - } - } - else - { - LOG_ERROR(RSX, "NV3062_SET_COLOR_FORMAT: unknown arg count (%d)", count); - } - break; - } - - // NV309E - case NV309E_SET_CONTEXT_DMA_IMAGE: - { - if (count == 1) - { - m_context_dma_img_src = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV309E_SET_CONTEXT_DMA_IMAGE: unknown arg count (%d)", count); - } - break; - } - - case NV309E_SET_FORMAT: - { - if (count == 2) - { - m_swizzle_format = ARGS(0); - m_swizzle_width = ARGS(0) >> 16; - m_swizzle_height = ARGS(0) >> 24; - m_swizzle_offset = ARGS(1); - } - else - { - LOG_ERROR(RSX, "NV309E_SET_FORMAT: unknown arg count (%d)", count); - } - break; - } - - // NV308A - case NV308A_POINT: - { - const u32 a0 = ARGS(0); - m_point_x = a0 & 0xffff; - m_point_y = a0 >> 16; - break; - } - - case NV308A_COLOR: - { - color4f c; - u32 id = m_dst_offset | ((u32)m_point_x << 2); - - if (count >= 1) - { - u32 a = ARGS(0); - a = a << 16 | a >> 16; - c.x = (float&)a; - } - - if (count >= 2) - { - u32 a = ARGS(1); - a = a << 16 | a >> 16; - c.y = (float&)a; - } - - if (count >= 3) - { - u32 a = ARGS(2); - a = a << 16 | a >> 16; - c.z = (float&)a; - } - - if (count >= 4) - { - u32 a = ARGS(3); - a = a << 16 | a >> 16; - c.w = (float&)a; - } - - if (count >= 5) - { - LOG_ERROR(RSX, "NV308A_COLOR: unknown arg count (%d)", count); - } - - fragment_constants[id] = c; - break; - } - - // NV3089 - case NV3089_SET_CONTEXT_DMA_IMAGE: - { - if (count == 1) - { - m_context_dma_img_src = ARGS(0); - } - else - { - LOG_ERROR(RSX, "NV3089_SET_CONTEXT_DMA_IMAGE: unknown arg count (%d)", count); - } - break; - } - - case NV3089_SET_CONTEXT_SURFACE: - { - if (count == 1) - { - m_context_surface = ARGS(0); - - if (m_context_surface != CELL_GCM_CONTEXT_SURFACE2D && m_context_surface != CELL_GCM_CONTEXT_SWIZZLE2D) - { - LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: unknown surface (0x%x)", ARGS(0)); - } - } - else - { - LOG_ERROR(RSX, "NV3089_SET_CONTEXT_SURFACE: unknown arg count (%d)", count); - } - break; - } - - case NV3089_IMAGE_IN_SIZE: - { - const u16 width = ARGS(0); - const u16 height = ARGS(0) >> 16; - const u16 pitch = ARGS(1); - - const u8 origin = ARGS(1) >> 16; - if (origin != 2 /* CELL_GCM_TRANSFER_ORIGIN_CORNER */) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", origin); - } - - const u8 inter = ARGS(1) >> 24; - if (inter != 0 /* CELL_GCM_TRANSFER_INTERPOLATOR_ZOH */ && inter != 1 /* CELL_GCM_TRANSFER_INTERPOLATOR_FOH */) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", inter); - } - - const u32 offset = ARGS(2); - - const u16 u = ARGS(3); // inX (currently ignored) - const u16 v = ARGS(3) >> 16; // inY (currently ignored) - - u8* pixels_src = vm::get_ptr(rsx::get_address(offset, m_context_dma_img_src - 0xfeed0000)); - u8* pixels_dst = vm::get_ptr(rsx::get_address(m_dst_offset, m_context_dma_img_dst - 0xfeed0000)); - - if (m_context_surface == CELL_GCM_CONTEXT_SWIZZLE2D) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: Swizzle2D not implemented"); - } - else if (m_context_surface != CELL_GCM_CONTEXT_SURFACE2D) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", m_context_surface); - } - - if (m_color_format != 4 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 */ && m_color_format != 10 /* CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8 */) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_color_format (%d)", m_color_format); - } - - const u32 in_bpp = m_color_format == 4 ? 2 : 4; // bytes per pixel - const u32 out_bpp = m_color_conv_fmt == 7 ? 2 : 4; - - const s32 out_w = (s32)(u64(width) * (1 << 20) / m_color_conv_dsdx); - const s32 out_h = (s32)(u64(height) * (1 << 20) / m_color_conv_dtdy); - - LOG_WARNING(RSX, "NV3089_IMAGE_IN_SIZE: w=%d, h=%d, pitch=%d, offset=0x%x, inX=%f, inY=%f, scaleX=%f, scaleY=%f", - width, height, pitch, offset, double(u) / 16, double(v) / 16, double(1 << 20) / (m_color_conv_dsdx), double(1 << 20) / (m_color_conv_dtdy)); - - std::unique_ptr temp; - - if (in_bpp != out_bpp && width != out_w && height != out_h) - { - // resize/convert if necessary - - temp.reset(new u8[out_bpp * out_w * out_h]); - - AVPixelFormat in_format = m_color_format == 4 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? - AVPixelFormat out_format = m_color_conv_fmt == 7 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; // ??? - - std::unique_ptr sws(sws_getContext(width, height, in_format, out_w, out_h, out_format, inter ? SWS_FAST_BILINEAR : SWS_POINT, NULL, NULL, NULL), sws_freeContext); - - int in_line = in_bpp * width; - u8* out_ptr = temp.get(); - int out_line = out_bpp * out_w; - - sws_scale(sws.get(), &pixels_src, &in_line, 0, height, &out_ptr, &out_line); - - pixels_src = temp.get(); // use resized image as a source - } - - if (m_color_conv_out_w != m_color_conv_clip_w || m_color_conv_out_w != out_w || - m_color_conv_out_h != m_color_conv_clip_h || m_color_conv_out_h != out_h || - m_color_conv_out_x || m_color_conv_out_y || m_color_conv_clip_x || m_color_conv_clip_y) - { - // clip if necessary - - for (s32 y = m_color_conv_clip_y, dst_y = m_color_conv_out_y; y < out_h; y++, dst_y++) - { - if (dst_y >= 0 && dst_y < m_color_conv_out_h) - { - // destination line - u8* dst_line = pixels_dst + dst_y * out_bpp * m_color_conv_out_w + std::min(std::max(m_color_conv_out_x, 0), m_color_conv_out_w); - size_t dst_max = std::min(std::max((s32)m_color_conv_out_w - m_color_conv_out_x, 0), m_color_conv_out_w) * out_bpp; - - if (y >= 0 && y < std::min(m_color_conv_clip_h, out_h)) - { - // source line - u8* src_line = pixels_src + y * out_bpp * out_w + std::min(std::max(m_color_conv_clip_x, 0), m_color_conv_clip_w); - size_t src_max = std::min(std::max((s32)m_color_conv_clip_w - m_color_conv_clip_x, 0), m_color_conv_clip_w) * out_bpp; - - std::pair - z0 = { src_line + 0, std::min(dst_max, std::max(0, m_color_conv_clip_x)) }, - d0 = { src_line + z0.second, std::min(dst_max - z0.second, src_max) }, - z1 = { src_line + d0.second, dst_max - z0.second - d0.second }; - - memset(z0.first, 0, z0.second); - memcpy(d0.first, src_line, d0.second); - memset(z1.first, 0, z1.second); - } - else - { - memset(dst_line, 0, dst_max); - } - } - } - } - else - { - memcpy(pixels_dst, pixels_src, out_w * out_h * out_bpp); - } - - break; - } - - case NV3089_SET_COLOR_CONVERSION: - { - m_color_conv = ARGS(0); - if (m_color_conv != 1 /* CELL_GCM_TRANSFER_CONVERSION_TRUNCATE */) - { - LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown color conv (%d)", m_color_conv); - } - - m_color_conv_fmt = ARGS(1); - if (m_color_conv_fmt != 3 /* CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8 */ && m_color_conv_fmt != 7 /* CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 */) - { - LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown format (%d)", m_color_conv_fmt); - } - - m_color_conv_op = ARGS(2); - if (m_color_conv_op != 3 /* CELL_GCM_TRANSFER_OPERATION_SRCCOPY */) - { - LOG_ERROR(RSX, "NV3089_SET_COLOR_CONVERSION: unknown color conv op (%d)", m_color_conv_op); - } - - m_color_conv_clip_x = ARGS(3); - m_color_conv_clip_y = ARGS(3) >> 16; - m_color_conv_clip_w = ARGS(4); - m_color_conv_clip_h = ARGS(4) >> 16; - m_color_conv_out_x = ARGS(5); - m_color_conv_out_y = ARGS(5) >> 16; - m_color_conv_out_w = ARGS(6); - m_color_conv_out_h = ARGS(6) >> 16; - m_color_conv_dsdx = ARGS(7); - m_color_conv_dtdy = ARGS(8); - break; - } - - case GCM_SET_USER_COMMAND: - { - const u32 cause = ARGS(0); - - if (auto cb = user_handler) - { - Emu.GetCallbackManager().Async([=](CPUThread& cpu) - { - cb(static_cast(cpu), cause); - }); - } - else - { - throw EXCEPTION("User handler not set"); - } - - break; - } - - // Note: What is this? NV4097 offsets? - case 0x000002c8: - case 0x000002d0: - case 0x000002d8: - case 0x000002e0: - case 0x000002e8: - case 0x000002f0: - case 0x000002f8: - break; - - // The existing GCM commands don't use any of the following NV4097 / NV0039 / NV3062 / NV309E / NV308A / NV3089 methods - case NV4097_SET_WINDOW_CLIP_TYPE: - case NV4097_SET_WINDOW_CLIP_HORIZONTAL: - case NV4097_SET_WINDOW_CLIP_VERTICAL: - { - LOG_WARNING(RSX, "Unused NV4097 method 0x%x detected!", cmd); - break; - } - - case NV0039_SET_CONTEXT_DMA_BUFFER_OUT: - case NV0039_PITCH_OUT: - case NV0039_LINE_LENGTH_IN: - case NV0039_LINE_COUNT: - case NV0039_FORMAT: - case NV0039_SET_OBJECT: - case NV0039_SET_CONTEXT_DMA_NOTIFIES: - { - LOG_WARNING(RSX, "Unused NV0039 method 0x%x detected!", cmd); - break; - } - - case NV3062_SET_OBJECT: - case NV3062_SET_CONTEXT_DMA_NOTIFIES: - case NV3062_SET_CONTEXT_DMA_IMAGE_SOURCE: - case NV3062_SET_PITCH: - case NV3062_SET_OFFSET_SOURCE: - { - LOG_WARNING(RSX, "Unused NV3062 method 0x%x detected!", cmd); - break; - } - - case NV308A_SET_OBJECT: - case NV308A_SET_CONTEXT_DMA_NOTIFIES: - case NV308A_SET_CONTEXT_COLOR_KEY: - case NV308A_SET_CONTEXT_CLIP_RECTANGLE: - case NV308A_SET_CONTEXT_PATTERN: - case NV308A_SET_CONTEXT_ROP: - case NV308A_SET_CONTEXT_BETA1: - case NV308A_SET_CONTEXT_BETA4: - case NV308A_SET_CONTEXT_SURFACE: - case NV308A_SET_COLOR_CONVERSION: - case NV308A_SET_OPERATION: - case NV308A_SET_COLOR_FORMAT: - case NV308A_SIZE_OUT: - case NV308A_SIZE_IN: - { - LOG_WARNING(RSX, "Unused NV308A method 0x%x detected!", cmd); - break; - } - - case NV309E_SET_OBJECT: - case NV309E_SET_CONTEXT_DMA_NOTIFIES: - case NV309E_SET_OFFSET: - { - LOG_WARNING(RSX, "Unused NV309E method 0x%x detected!", cmd); - break; - } - - case NV3089_SET_OBJECT: - case NV3089_SET_CONTEXT_DMA_NOTIFIES: - case NV3089_SET_CONTEXT_PATTERN: - case NV3089_SET_CONTEXT_ROP: - case NV3089_SET_CONTEXT_BETA1: - case NV3089_SET_CONTEXT_BETA4: - case NV3089_SET_COLOR_FORMAT: - case NV3089_SET_OPERATION: - case NV3089_CLIP_POINT: - case NV3089_CLIP_SIZE: - case NV3089_IMAGE_OUT_POINT: - case NV3089_IMAGE_OUT_SIZE: - case NV3089_DS_DX: - case NV3089_DT_DY: - case NV3089_IMAGE_IN_FORMAT: - case NV3089_IMAGE_IN_OFFSET: - case NV3089_IMAGE_IN: - { - LOG_WARNING(RSX, "Unused NV3089 methods 0x%x detected!", cmd); - break; - } - - default: - { - std::string log = GetMethodName(cmd); - log += "("; - for (u32 i = 0; i < count; ++i) - { - log += (i ? ", " : "") + fmt::format("0x%x", ARGS(i)); - } - log += ")"; - LOG_ERROR(RSX, "TODO: %s", log.c_str()); - break; - } - } -} - - void thread::begin(u32 drawMode) - { - m_begin_end = 1; - draw_mode = drawMode; - draw_array_count = 0; - draw_array_first = ~0; + draw_mode = method_registers[NV4097_SET_BEGIN_END]; } void thread::end() { - for (auto &vdata : vertex_arrays) - { - vdata.clear(); - } + vertex_index_array.clear(); + for (auto &vertex_array : vertex_arrays) + vertex_array.clear(); - m_indexed_array.Reset(); - fragment_constants.clear(); - - m_clear_surface_mask = 0; - m_begin_end = 0; - - OnReset(); + transform_constants.clear(); } void thread::task() @@ -2108,7 +925,7 @@ void thread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 last_flip_time = get_system_time() - 1000000; - autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() + autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() { const u64 start_time = get_system_time(); @@ -2129,83 +946,120 @@ void thread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 cb(static_cast(cpu), 1); }); } + + continue; } - else - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } + + std::this_thread::sleep_for(1ms); // hack } }); - while (joinable() && !Emu.IsStopped()) + reset(); + + try { - std::lock_guard lock(cs_main); - - inc = 1; - - const be_t put = ctrl->put; - const be_t get = ctrl->get; - - if (put == get || !Emu.IsRunning()) + while (joinable()) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - continue; - } + //TODO: async mode + if (Emu.IsStopped()) + { + LOG_WARNING(RSX, "RSX thread aborted"); + break; + } + std::lock_guard lock(cs_main); - const u32 cmd = ReadIO32(get); - const u32 count = (cmd >> 18) & 0x7ff; + inc = 1; - if (Ini.RSXLogging.GetValue()) - { - LOG_NOTICE(Log::RSX, "%s (cmd=0x%x)", GetMethodName(cmd & 0xffff).c_str(), cmd); - } - - if (cmd & CELL_GCM_METHOD_FLAG_JUMP) - { - u32 offs = cmd & 0x1fffffff; - //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); - ctrl->get.exchange(offs); - continue; - } - if (cmd & CELL_GCM_METHOD_FLAG_CALL) - { - m_call_stack.push(get + 4); - u32 offs = cmd & ~3; - //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); - ctrl->get.exchange(offs); - continue; - } - if (cmd == CELL_GCM_METHOD_FLAG_RETURN) - { - u32 get = m_call_stack.top(); - m_call_stack.pop(); - //LOG_WARNING(RSX, "rsx return(0x%x)", get); - ctrl->get.exchange(get); - continue; - } - if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) - { - //LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd); - inc = 0; - } + be_t get = ctrl->get; + be_t put = ctrl->put; - if (cmd == 0) //nop - { - ctrl->get += 4; - continue; + if (put == get || !Emu.IsRunning()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + continue; + } + + const u32 cmd = ReadIO32(get); + const u32 count = (cmd >> 18) & 0x7ff; + + if (cmd & CELL_GCM_METHOD_FLAG_JUMP) + { + u32 offs = cmd & 0x1fffffff; + //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); + ctrl->get.exchange(offs); + continue; + } + if (cmd & CELL_GCM_METHOD_FLAG_CALL) + { + m_call_stack.push(get + 4); + u32 offs = cmd & ~3; + //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); + ctrl->get.exchange(offs); + continue; + } + if (cmd == CELL_GCM_METHOD_FLAG_RETURN) + { + u32 get = m_call_stack.top(); + m_call_stack.pop(); + //LOG_WARNING(RSX, "rsx return(0x%x)", get); + ctrl->get.exchange(get); + continue; + } + if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) + { + //LOG_WARNING(RSX, "rsx non increment cmd! 0x%x", cmd); + inc = 0; + } + + if (cmd == 0) //nop + { + ctrl->get.atomic_op([](be_t& value) + { + value += 4; + }); + + continue; + } + + auto args = vm::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); + + u32 first_cmd = (cmd & 0xffff) >> 2; + + if (cmd & 0x3) + { + LOG_WARNING(Log::RSX, "unaligned command: %s (0x%x from 0x%x)", get_method_name(first_cmd).c_str(), first_cmd, cmd & 0xffff); + } + + for (u32 i = 0; i < count; i++) + { + u32 reg = first_cmd + (i * inc); + u32 value = args[i]; + + if (Ini.RSXLogging.GetValue()) + { + LOG_NOTICE(Log::RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value); + } + + method_registers[reg] = value; + + if (auto method = methods[reg]) + method(this, value); + } + + ctrl->get.atomic_op([count](be_t& value) + { + value += (count + 1) * 4; + }); } - - auto args = vm::ps3::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); - - for (u32 i = 0; i < count; i++) - { - rsx::method_registers[(cmd & 0xffff) + (i * 4 * inc)] = ARGS(i); - } - - DoCmd(cmd, cmd & 0x3ffff, args.addr(), count); - - ctrl->get += (count + 1) * 4; } + catch (const std::exception& ex) + { + LOG_ERROR(Log::RSX, ex.what()); + + std::rethrow_exception(std::current_exception()); + } + + LOG_NOTICE(RSX, "RSX thread ended"); onexit_thread(); } @@ -2218,79 +1072,95 @@ void thread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 void thread::reset() { - rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false; - rsx::method_registers[NV4097_SET_DEPTH_MASK] = 1; - rsx::method_registers[NV4097_SET_DEPTH_FUNC] = 0x0201; + //setup method registers + memset(method_registers, 0, sizeof(method_registers)); - m_set_dither = false; - rsx::method_registers[NV4097_SET_COLOR_MASK] = -1; - m_set_clip = false; - m_set_depth_bounds_test = false; - m_set_depth_bounds = false; - m_set_scissor_horizontal = false; - m_set_scissor_vertical = false; - m_set_front_polygon_mode = false; - m_set_back_polygon_mode = false; - rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0; - rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; - m_set_two_side_light_enable = false; - m_set_point_sprite_control = false; - m_set_point_size = false; - m_set_line_width = false; - m_set_line_smooth = false; - m_set_shade_mode = false; - m_set_fog_mode = false; - m_set_fog_params = false; - m_set_clip_plane = false; - rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false; - rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; - rsx::method_registers[NV4097_SET_ALPHA_FUNC] = false; - rsx::method_registers[NV4097_SET_ALPHA_REF] = false; - m_set_poly_smooth = false; - m_set_poly_offset_fill = false; - m_set_poly_offset_line = false; - m_set_poly_offset_point = false; - m_set_poly_offset_mode = false; - m_set_restart_index = false; - m_set_specular = false; - m_set_line_stipple = false; - m_set_polygon_stipple = false; - m_set_surface_clip_horizontal = false; - m_set_surface_clip_vertical = false; + method_registers[NV4097_SET_COLOR_MASK] = CELL_GCM_COLOR_MASK_R | CELL_GCM_COLOR_MASK_G | CELL_GCM_COLOR_MASK_B | CELL_GCM_COLOR_MASK_A; + method_registers[NV4097_SET_SCISSOR_HORIZONTAL] = (4096 << 16) | 0; + method_registers[NV4097_SET_SCISSOR_VERTICAL] = (4096 << 16) | 0; - m_clear_surface_mask = 0; - m_begin_end = 0; + method_registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; + method_registers[NV4097_SET_ALPHA_REF] = 0; - for (uint i = 0; i < rsx::limits::textures_count; ++i) + method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = (CELL_GCM_ONE << 16) | CELL_GCM_ONE; + method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = (CELL_GCM_ZERO << 16) | CELL_GCM_ZERO; + method_registers[NV4097_SET_BLEND_COLOR] = 0; + method_registers[NV4097_SET_BLEND_COLOR2] = 0; + method_registers[NV4097_SET_BLEND_EQUATION] = (CELL_GCM_FUNC_ADD << 16) | CELL_GCM_FUNC_ADD; + + method_registers[NV4097_SET_STENCIL_MASK] = 0xff; + method_registers[NV4097_SET_STENCIL_FUNC] = CELL_GCM_ALWAYS; + method_registers[NV4097_SET_STENCIL_FUNC_REF] = 0x00; + method_registers[NV4097_SET_STENCIL_FUNC_MASK] = 0xff; + method_registers[NV4097_SET_STENCIL_OP_FAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_STENCIL_OP_ZPASS] = CELL_GCM_KEEP; + + method_registers[NV4097_SET_BACK_STENCIL_MASK] = 0xff; + method_registers[NV4097_SET_BACK_STENCIL_FUNC] = CELL_GCM_ALWAYS; + method_registers[NV4097_SET_BACK_STENCIL_FUNC_REF] = 0x00; + method_registers[NV4097_SET_BACK_STENCIL_FUNC_MASK] = 0xff; + method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; + method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS] = CELL_GCM_KEEP; + + method_registers[NV4097_SET_SHADE_MODE] = CELL_GCM_SMOOTH; + + method_registers[NV4097_SET_LOGIC_OP] = CELL_GCM_COPY; + + (f32&)method_registers[NV4097_SET_DEPTH_BOUNDS_MIN] = 0.f; + (f32&)method_registers[NV4097_SET_DEPTH_BOUNDS_MAX] = 1.f; + + (f32&)method_registers[NV4097_SET_CLIP_MIN] = 0.f; + (f32&)method_registers[NV4097_SET_CLIP_MAX] = 1.f; + + method_registers[NV4097_SET_LINE_WIDTH] = 1 << 3; + + method_registers[NV4097_SET_FOG_MODE] = CELL_GCM_FOG_MODE_EXP; + + method_registers[NV4097_SET_DEPTH_FUNC] = CELL_GCM_LESS; + method_registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE; + (f32&)method_registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR] = 0.f; + (f32&)method_registers[NV4097_SET_POLYGON_OFFSET_BIAS] = 0.f; + method_registers[NV4097_SET_FRONT_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; + method_registers[NV4097_SET_BACK_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; + method_registers[NV4097_SET_CULL_FACE] = CELL_GCM_BACK; + method_registers[NV4097_SET_FRONT_FACE] = CELL_GCM_CCW; + method_registers[NV4097_SET_RESTART_INDEX] = -1; + + method_registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] = (4096 << 16) | 0; + method_registers[NV4097_SET_CLEAR_RECT_VERTICAL] = (4096 << 16) | 0; + + method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; + + // Construct Textures + for (int i = 0; i < limits::textures_count; i++) { textures[i].init(i); } } - void thread::init(const u32 ioAddress, const u32 io_size, const u32 ctrlAddress, const u32 localAddress) + void thread::init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) { ctrl = vm::get_ptr(ctrlAddress); this->ioAddress = ioAddress; - this->ioSize = io_size; - m_ctrlAddress = ctrlAddress; + this->ioSize = ioSize; local_mem_addr = localAddress; - - m_cur_vertex_prog = nullptr; + flip_status = 0; m_used_gcm_commands.clear(); oninit(); - - start(WRAP_EXPR("RSXThread"), WRAP_EXPR(task())); + named_thread_t::start(WRAP_EXPR("rsx::thread"), WRAP_EXPR(task())); } u32 thread::ReadIO32(u32 addr) { u32 value; - + if (!RSXIOMem.Read32(addr, &value)) { - throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + throw EXCEPTION("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr); } return value; @@ -2300,7 +1170,7 @@ void thread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 { if (!RSXIOMem.Write32(addr, value)) { - throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); + throw EXCEPTION("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr); } } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 0e12249c5d..5aa51ae326 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -10,42 +10,6 @@ #include "Utilities/Timer.h" #include "Utilities/types.h" -enum Method -{ - CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000, - CELL_GCM_METHOD_FLAG_JUMP = 0x20000000, - CELL_GCM_METHOD_FLAG_CALL = 0x00000002, - CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, -}; - -struct RSXIndexArrayData -{ - std::vector m_data; - int m_type; - u32 m_first; - u32 m_count; - u32 m_addr; - u32 index_max; - u32 index_min; - - RSXIndexArrayData() - { - Reset(); - } - - void Reset() - { - m_type = 0; - m_first = ~0; - m_count = 0; - m_addr = 0; - index_min = ~0; - index_max = 0; - m_data.clear(); - } -}; - - namespace rsx { namespace limits @@ -62,6 +26,67 @@ namespace rsx }; } + //TODO + union alignas(4) method_registers_t + { + u8 _u8[0x10000]; + u32 _u32[0x10000 >> 2]; +/* + struct alignas(4) + { + u8 pad[NV4097_SET_TEXTURE_OFFSET - 4]; + + struct alignas(4) texture_t + { + u32 offset; + + union format_t + { + u32 _u32; + + struct + { + u32: 1; + u32 location : 1; + u32 cubemap : 1; + u32 border_type : 1; + u32 dimension : 4; + u32 format : 8; + u32 mipmap : 16; + }; + } format; + + union address_t + { + u32 _u32; + + struct + { + u32 wrap_s : 4; + u32 aniso_bias : 4; + u32 wrap_t : 4; + u32 unsigned_remap : 4; + u32 wrap_r : 4; + u32 gamma : 4; + u32 signed_remap : 4; + u32 zfunc : 4; + }; + } address; + + u32 control0; + u32 control1; + u32 filter; + u32 image_rect; + u32 border_color; + } textures[limits::textures_count]; + }; +*/ + u32& operator[](int index) + { + return _u32[index >> 2]; + } + }; + extern u32 method_registers[0x10000 >> 2]; u32 get_address(u32 offset, u32 location); @@ -120,23 +145,26 @@ namespace rsx public: CellGcmControl* ctrl = nullptr; + Timer timer_sync; GcmTileInfo tiles[limits::tiles_count]; GcmZcullInfo zculls[limits::zculls_count]; - texture textures[limits::textures_count]; - vertex_texture m_vertex_textures[limits::vertex_textures_count]; + + rsx::texture textures[limits::textures_count]; + rsx::vertex_texture vertex_textures[limits::vertex_textures_count]; data_array_format_info vertex_arrays_info[limits::vertex_count]; std::vector vertex_arrays[limits::vertex_count]; - RSXIndexArrayData m_indexed_array; + std::vector vertex_index_array; + u32 vertex_draw_count = 0; std::unordered_map> transform_constants; - std::unordered_map> fragment_constants; - u32 m_shader_ctrl; - RSXVertexProgram m_vertex_progs[limits::vertex_count]; - RSXVertexProgram* m_cur_vertex_prog; + u32 transform_program[512 * 4] = {}; + + void load_vertex_data(u32 first, u32 count); + void load_vertex_index_data(u32 first, u32 count); public: u32 ioAddress, ioSize; @@ -147,7 +175,7 @@ namespace rsx u32 tiles_addr; u32 zculls_addr; - u32 m_gcm_buffers_addr; + vm::ps3::ptr gcm_buffers; u32 gcm_buffers_count; u32 gcm_current_buffer; u32 ctxt_addr; @@ -155,16 +183,13 @@ namespace rsx u32 label_addr; u32 draw_mode; - // DMA - u32 dma_report; - u32 local_mem_addr, main_mem_addr; bool strict_ordering[0x1000]; public: u32 draw_array_count; u32 draw_array_first; - double m_fps_limit = 59.94; + double fps_limit = 59.94; public: std::mutex cs_main; @@ -182,7 +207,7 @@ namespace rsx virtual ~thread() {} public: - virtual void begin(u32 draw_mode); + virtual void begin(); virtual void end(); virtual void oninit() = 0; @@ -200,293 +225,5 @@ namespace rsx u32 ReadIO32(u32 addr); void WriteIO32(u32 addr, u32 value); - - public: - u32 m_ctrlAddress; - u32 m_width; - u32 m_height; - float m_width_scale; - float m_height_scale; - // Dither - bool m_set_dither; - - // Clip - bool m_set_clip; - float m_clip_min; - float m_clip_max; - - // Depth bound test - bool m_set_depth_bounds_test; - bool m_set_depth_bounds; - float m_depth_bounds_min; - float m_depth_bounds_max; - - // Primitive restart - bool m_set_restart_index; - u32 m_restart_index; - - // Point - bool m_set_point_size; - bool m_set_point_sprite_control; - float m_point_size; - u16 m_point_x; - u16 m_point_y; - - // Line smooth - bool m_set_line_smooth; - - // Viewport & scissor - bool m_set_scissor_horizontal; - bool m_set_scissor_vertical; - u16 m_scissor_x; - u16 m_scissor_y; - u16 m_scissor_w; - u16 m_scissor_h; - - // Polygon mode/offset - bool m_set_poly_smooth; - bool m_set_poly_offset_fill; - bool m_set_poly_offset_line; - bool m_set_poly_offset_point; - bool m_set_front_polygon_mode; - u32 m_front_polygon_mode; - bool m_set_back_polygon_mode; - u32 m_back_polygon_mode; - bool m_set_poly_offset_mode; - float m_poly_offset_scale_factor; - float m_poly_offset_bias; - - // Line/Polygon stipple - bool m_set_line_stipple; - u16 m_line_stipple_pattern; - u16 m_line_stipple_factor; - bool m_set_polygon_stipple; - u32 m_polygon_stipple_pattern[32]; - - - // Clearing - u32 m_clear_surface_mask; - - // Stencil Test - bool m_set_two_side_light_enable; - - // Line width - bool m_set_line_width; - float m_line_width; - - // Shader mode - bool m_set_shade_mode; - u32 m_shade_mode; - - // Lighting - bool m_set_specular; - - // Color - u32 m_color_format; - u16 m_color_format_src_pitch; - u16 m_color_format_dst_pitch; - u32 m_color_conv; - u32 m_color_conv_fmt; - u32 m_color_conv_op; - s16 m_color_conv_clip_x; - s16 m_color_conv_clip_y; - u16 m_color_conv_clip_w; - u16 m_color_conv_clip_h; - s16 m_color_conv_out_x; - s16 m_color_conv_out_y; - u16 m_color_conv_out_w; - u16 m_color_conv_out_h; - s32 m_color_conv_dsdx; - s32 m_color_conv_dtdy; - - // Semaphore - // PGRAPH - u32 m_PGRAPH_semaphore_offset; - //PFIFO - u32 m_PFIFO_semaphore_offset; - u32 m_PFIFO_semaphore_release_value; - - // Fog - bool m_set_fog_mode; - u32 m_fog_mode; - bool m_set_fog_params; - float m_fog_param0; - float m_fog_param1; - - // Clip plane - bool m_set_clip_plane; - bool m_clip_plane_0; - bool m_clip_plane_1; - bool m_clip_plane_2; - bool m_clip_plane_3; - bool m_clip_plane_4; - bool m_clip_plane_5; - - // Surface - rsx::surface_info m_surface; - bool m_set_surface_clip_horizontal; - bool m_set_surface_clip_vertical; - - // DMA context - u32 m_context_surface; - u32 m_context_dma_img_src; - u32 m_context_dma_img_dst; - u32 m_context_dma_buffer_in_src; - u32 m_context_dma_buffer_in_dst; - u32 m_dst_offset; - - // Swizzle2D? - u16 m_swizzle_format; - u8 m_swizzle_width; - u8 m_swizzle_height; - u32 m_swizzle_offset; - - // Shader - u16 m_shader_window_height; - u8 m_shader_window_origin; - u16 m_shader_window_pixel_centers; - - // Vertex Data - u32 m_vertex_data_base_index; - - // Frequency divider - u32 m_set_frequency_divider_operation; - - u8 m_begin_end; - bool m_read_buffer; - - protected: - thread() - : m_shader_ctrl(0x40) - , flip_status(0) - , flip_mode(CELL_GCM_DISPLAY_VSYNC) - , debug_level(CELL_GCM_DEBUG_LEVEL0) - , frequency_mode(CELL_GCM_DISPLAY_FREQUENCY_DISABLE) - , report_main_addr(0) - , main_mem_addr(0) - , local_mem_addr(0) - , draw_mode(0) - , draw_array_count(0) - , draw_array_first(~0) - , gcm_current_buffer(0) - , m_read_buffer(true) - { - flip_handler.set(0); - vblank_handler.set(0); - user_handler.set(0); - rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] = false; - m_set_depth_bounds_test = false; - rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = 0; - rsx::method_registers[NV4097_SET_BLEND_ENABLE] = false; - m_set_dither = false; - m_set_scissor_horizontal = false; - m_set_scissor_vertical = false; - m_set_line_smooth = false; - m_set_poly_smooth = false; - m_set_point_sprite_control = false; - m_set_specular = false; - m_set_two_side_light_enable = false; - m_set_surface_clip_horizontal = false; - m_set_surface_clip_vertical = false; - m_set_poly_offset_fill = false; - m_set_poly_offset_line = false; - m_set_poly_offset_point = false; - m_set_restart_index = false; - m_set_line_stipple = false; - m_set_polygon_stipple = false; - - // Default value - // TODO: Check against the default value on PS3 - rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE] = 0; - rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffff << 8; - m_poly_offset_scale_factor = 0.0; - m_poly_offset_bias = 0.0; - m_restart_index = 0xffffffff; - m_front_polygon_mode = 0x1b02; // GL_FILL - m_back_polygon_mode = 0x1b02; // GL_FILL - rsx::method_registers[NV4097_SET_FRONT_FACE] = 0x0901; // GL_CCW - rsx::method_registers[NV4097_SET_CULL_FACE] = 0x0405; // GL_BACK - rsx::method_registers[NV4097_SET_ALPHA_FUNC] = 0x0207; // GL_ALWAYS - rsx::method_registers[NV4097_SET_ALPHA_REF] = 0.0f; - m_shade_mode = 0x1D01; // GL_SMOOTH - - m_depth_bounds_min = 0.0; - m_depth_bounds_max = 1.0; - m_clip_min = 0.0; - m_clip_max = 1.0; - rsx::method_registers[NV4097_SET_BLEND_EQUATION] = (0x8006) | (0x8006 << 16); // GL_FUNC_ADD - rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = 1 | (1 << 16); - rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = 0; - m_point_x = 0; - m_point_y = 0; - m_point_size = 1.0; - m_line_width = 1.0; - m_line_stipple_pattern = 0xffff; - m_line_stipple_factor = 1; - rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET] = 0; - m_vertex_data_base_index = 0; - - // Construct Stipple Pattern - for (size_t i = 0; i < 32; i++) - { - m_polygon_stipple_pattern[i] = 0xFFFFFFFF; - } - - // Construct Textures - for (int i = 0; i < 16; i++) - { - textures[i] = rsx::texture(); - } - - reset(); - } - - u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr); - void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count); - - virtual void OnReset() = 0; - - /** - * This member is called when RSXThread parse a TEXTURE_READ_SEMAPHORE_RELEASE - * command. - * Backend is expected to write value at offset when current draw textures aren't - * needed anymore by the GPU and can be modified. - */ - virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) = 0; - /** - * This member is called when RSXThread parse a BACK_END_WRITE_SEMAPHORE_RELEASE - * command. - * Backend is expected to write value at offset when current draw call has completed - * and render surface can be used. - */ - virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) = 0; - /** - * This member is called when RSXThread parse a SEMAPHORE_ACQUIRE command. - * Backend and associated GPU is expected to wait that memory at offset is the same - * as value. In particular buffer/texture buffers value can change while backend is - * waiting. - */ - virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0; - /** - * Called when vertex or fragment shader changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyProgramChange() = 0; - /** - * Called when blend state changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyBlendStateChange() = 0; - /** - * Called when depth stencil state changes. - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyDepthStencilStateChange() = 0; - /** - * Called when rasterizer state changes. - * Rasterizer state includes culling, color masking - * Backend can reuse same program if no change has been notified. - */ - virtual void notifyRasterizerStateChange() = 0; }; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index a31eb7ab4c..7fff720d12 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -389,7 +389,7 @@ s32 _cellGcmInitBody(vm::pptr context, u32 cmdSize, u32 ioSi auto& render = Emu.GetGSManager().GetRender(); render.ctxt_addr = context.addr(); - render.m_gcm_buffers_addr = vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main); + render.gcm_buffers = { vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main) }; render.zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main); render.tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main); render.gcm_buffers_count = 0; @@ -438,7 +438,7 @@ s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height return CELL_EINVAL; } - auto buffers = vm::get_ptr(Emu.GetGSManager().GetRender().m_gcm_buffers_addr); + auto buffers = Emu.GetGSManager().GetRender().gcm_buffers; buffers[id].offset = offset; buffers[id].pitch = pitch; @@ -504,14 +504,23 @@ s32 cellGcmSetPrepareFlip(PPUThread& ppu, vm::ptr ctxt, u32 return res; } } - - *ctxt->current++ = 0x3fead | (1 << 18); +#ifdef __GNUC__ + //gcc internal compiler error, try to avoid it for now + *ctxt->current++ = (GCM_FLIP_COMMAND << 2) | (1 << 18); *ctxt->current++ = id; if (ctxt.addr() == gcm_info.context_addr) { - vm::get_ref(gcm_info.control_addr).put += 8; + vm::get_ref(gcm_info.control_addr).put += 2 * sizeof(u32); } +#else + u32 command_size = rsx::make_command(ctxt->current, GCM_FLIP_COMMAND, id); + + if (ctxt.addr() == gcm_info.context_addr) + { + vm::get_ref(gcm_info.control_addr).put += command_size * sizeof(u32); + } +#endif return id; } @@ -535,7 +544,7 @@ s32 cellGcmSetSecondVFrequency(u32 freq) switch (freq) { case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ: - Emu.GetGSManager().GetRender().frequency_mode = freq; Emu.GetGSManager().GetRender().m_fps_limit = 59.94; break; + Emu.GetGSManager().GetRender().frequency_mode = freq; Emu.GetGSManager().GetRender().fps_limit = 59.94; break; case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT: Emu.GetGSManager().GetRender().frequency_mode = freq; cellGcmSys.Todo("Unimplemented display frequency: Scanout"); break; case CELL_GCM_DISPLAY_FREQUENCY_DISABLE: @@ -583,7 +592,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u tile.base = base; tile.bank = bank; - vm::get_ptr(Emu.GetGSManager().GetRender().tiles_addr)[index] = tile.Pack(); + vm::get_ptr(Emu.GetGSManager().GetRender().tiles_addr)[index] = tile.pack(); return CELL_OK; } @@ -644,7 +653,7 @@ s32 cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, zcull.sRef = sRef; zcull.sMask = sMask; - vm::get_ptr(Emu.GetGSManager().GetRender().zculls_addr)[index] = zcull.Pack(); + vm::get_ptr(Emu.GetGSManager().GetRender().zculls_addr)[index] = zcull.pack(); return CELL_OK; } @@ -694,8 +703,8 @@ u32 cellGcmGetZcullInfo() u32 cellGcmGetDisplayInfo() { - cellGcmSys.Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().m_gcm_buffers_addr); - return Emu.GetGSManager().GetRender().m_gcm_buffers_addr; + cellGcmSys.Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().gcm_buffers.addr()); + return Emu.GetGSManager().GetRender().gcm_buffers.addr(); } s32 cellGcmGetCurrentDisplayBufferId(vm::ptr id) @@ -1174,7 +1183,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co tile.base = base; tile.bank = bank; - vm::get_ptr(Emu.GetGSManager().GetRender().tiles_addr)[index] = tile.Pack(); + vm::get_ptr(Emu.GetGSManager().GetRender().tiles_addr)[index] = tile.pack(); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 4670c031bc..6d37b59f9e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -475,28 +475,28 @@ void SetupRsxRenderingStates(vm::ptr& cntxt) rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] = false; // r.m_set_logic_op = false; rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE] = false; - r.m_set_depth_bounds_test = false; +// r.m_set_depth_bounds_test = false; rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE] = false; - r.m_set_poly_offset_fill = false; +// r.m_set_poly_offset_fill = false; // r.m_set_stencil_test = false; // r.m_set_two_sided_stencil_test_enable = false; - r.m_set_two_side_light_enable = false; - r.m_set_point_sprite_control = false; - r.m_set_dither = true; - r.m_set_shade_mode = true; r.m_shade_mode = CELL_GCM_SMOOTH; - r.m_set_frequency_divider_operation = CELL_GCM_FREQUENCY_DIVIDE; +// r.m_set_two_side_light_enable = false; +// r.m_set_point_sprite_control = false; +// r.m_set_dither = true; +// r.m_set_shade_mode = true; r.m_shade_mode = CELL_GCM_SMOOTH; +// r.m_set_frequency_divider_operation = CELL_GCM_FREQUENCY_DIVIDE; rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] = s_rescInternalInstance->m_dstWidth << 16; rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] = s_rescInternalInstance->m_dstHeight << 16; - r.m_set_scissor_horizontal = r.m_set_scissor_vertical = true; - r.m_scissor_x = 0; - r.m_scissor_y = 0; - r.m_scissor_w = s_rescInternalInstance->m_dstWidth; - r.m_scissor_h = s_rescInternalInstance->m_dstHeight; +// r.m_set_scissor_horizontal = r.m_set_scissor_vertical = true; +// r.m_scissor_x = 0; +// r.m_scissor_y = 0; +// r.m_scissor_w = s_rescInternalInstance->m_dstWidth; +// r.m_scissor_h = s_rescInternalInstance->m_dstHeight; - r.m_width = s_rescInternalInstance->m_dstWidth; - r.m_height = s_rescInternalInstance->m_dstHeight; +// r.m_width = s_rescInternalInstance->m_dstWidth; +// r.m_height = s_rescInternalInstance->m_dstHeight; // r.m_surface_depth_format = 2; rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET] = 1; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 3a4a9017e4..dc7608d11c 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -215,7 +215,8 @@ void Emulator::Load() LOG_NOTICE(LOADER, "Resolution: %s", Ini.ResolutionIdToString(Ini.GSResolution.GetValue())); LOG_NOTICE(LOADER, "Write Depth Buffer: %s", Ini.GSDumpDepthBuffer.GetValue() ? "Yes" : "No"); LOG_NOTICE(LOADER, "Write Color Buffers: %s", Ini.GSDumpColorBuffers.GetValue() ? "Yes" : "No"); - LOG_NOTICE(LOADER, "Read Color Buffer: %s", Ini.GSReadColorBuffer.GetValue() ? "Yes" : "No"); + LOG_NOTICE(LOADER, "Read Color Buffers: %s", Ini.GSReadColorBuffers.GetValue() ? "Yes" : "No"); + LOG_NOTICE(LOADER, "Read Depth Buffer: %s", Ini.GSReadDepthBuffer.GetValue() ? "Yes" : "No"); LOG_NOTICE(LOADER, "Audio Out: %s", Ini.AudioOutIdToString(Ini.AudioOutMode.GetValue())); LOG_NOTICE(LOADER, "Log Everything: %s", Ini.HLELogging.GetValue() ? "Yes" : "No"); LOG_NOTICE(LOADER, "RSX Logging: %s", Ini.RSXLogging.GetValue() ? "Yes" : "No"); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 0c3b730a08..81e2799a4d 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -3,6 +3,10 @@ #include "Loader/Loader.h" #include "DbgCommand.h" +//just for frame_type +//TODO: provide better way +#include "Emu/RSX/GSRender.h" + struct EmuCallbacks { std::function)> call_after; @@ -11,7 +15,7 @@ struct EmuCallbacks std::function()> get_kb_handler; std::function()> get_mouse_handler; std::function()> get_pad_handler; - std::function(enum class frame_type)> get_gs_frame; + std::function(frame_type)> get_gs_frame; std::function()> get_msg_dialog; std::function()> get_save_dialog; }; diff --git a/rpcs3/Gui/GLGSFrame.cpp b/rpcs3/Gui/GLGSFrame.cpp index adc3b2327f..67e88bccae 100644 --- a/rpcs3/Gui/GLGSFrame.cpp +++ b/rpcs3/Gui/GLGSFrame.cpp @@ -1,27 +1,14 @@ #include "stdafx_gui.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "GLGSFrame.h" -#include "Utilities/Timer.h" - -#ifndef _WIN32 -#include "frame_icon.xpm" -#endif GLGSFrame::GLGSFrame() : GSFrame("OpenGL") { - SetIcon(wxICON(frame_icon)); m_canvas = new wxGLCanvas(this, wxID_ANY, NULL); m_canvas->SetSize(GetClientSize()); m_canvas->Bind(wxEVT_LEFT_DCLICK, &GSFrame::OnLeftDclick, this); } -GLGSFrame::~GLGSFrame() -{ -} - void* GLGSFrame::make_context() { return new wxGLContext(m_canvas); @@ -40,7 +27,9 @@ void GLGSFrame::delete_context(void* ctx) void GLGSFrame::flip(draw_context_t context) { GSFrame::flip(context); + if (!m_canvas) return; + m_canvas->SetCurrent(*(wxGLContext*)context.get()); m_canvas->SwapBuffers(); } @@ -49,5 +38,6 @@ void GLGSFrame::OnSize(wxSizeEvent& event) { if (m_canvas) m_canvas->SetSize(GetClientSize()); + event.Skip(); } \ No newline at end of file diff --git a/rpcs3/Gui/GLGSFrame.h b/rpcs3/Gui/GLGSFrame.h index 1c250cc7ff..c73b47e10a 100644 --- a/rpcs3/Gui/GLGSFrame.h +++ b/rpcs3/Gui/GLGSFrame.h @@ -1,20 +1,18 @@ #pragma once -#include "Emu/RSX/GL/GLGSRender.h" #include "Gui/GSFrame.h" #include "wx/glcanvas.h" class GLGSFrame : public GSFrame { wxGLCanvas* m_canvas; - u32 m_frames; + public: GLGSFrame(); - ~GLGSFrame(); - virtual void* make_context() override; - virtual void set_current(draw_context_t context) override; - virtual void delete_context(void* ctx) override; - virtual void flip(draw_context_t context) override; + void* make_context() override; + void set_current(draw_context_t context) override; + void delete_context(void* context) override; + void flip(draw_context_t context) override; private: virtual void OnSize(wxSizeEvent& event); diff --git a/rpcs3/Gui/GSFrame.cpp b/rpcs3/Gui/GSFrame.cpp index 613f1b35b8..00f5908740 100644 --- a/rpcs3/Gui/GSFrame.cpp +++ b/rpcs3/Gui/GSFrame.cpp @@ -3,14 +3,21 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules/cellVideoOut.h" #include "rpcs3.h" +#include "Utilities/Timer.h" + +#ifndef _WIN32 +#include "frame_icon.xpm" +#endif BEGIN_EVENT_TABLE(GSFrame, wxFrame) EVT_PAINT(GSFrame::OnPaint) EVT_SIZE(GSFrame::OnSize) END_EVENT_TABLE() -GSFrame::GSFrame(const wxString& title) : wxFrame(nullptr, wxID_ANY, title) +GSFrame::GSFrame(const wxString& title) : wxFrame(nullptr, wxID_ANY, "GSFrame[" + title + "]") { + SetIcon(wxICON(frame_icon)); + CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum(Ini.GSResolution.GetValue())]; SetClientSize(res.width, res.height); wxGetApp().Bind(wxEVT_KEY_DOWN, &GSFrame::OnKeyDown, this); @@ -27,19 +34,6 @@ void GSFrame::OnClose(wxCloseEvent& event) Emu.Stop(); } -/* -void GSFrame::OnSize(wxSizeEvent&) -{ -const wxSize client = GetClientSize(); -const wxSize viewport = AspectRatio(client, m_size); - -const int x = (client.GetX() - viewport.GetX()) / 2; -const int y = (client.GetY() - viewport.GetY()) / 2; - -SetViewport(wxPoint(x, y), viewport); -} -*/ - void GSFrame::OnKeyDown(wxKeyEvent& event) { switch (event.GetKeyCode()) @@ -93,6 +87,12 @@ void GSFrame::delete_context(void* ctx) { } +size2i GSFrame::client_size() +{ + wxSize size = GetClientSize(); + return{ size.GetWidth(), size.GetHeight() }; +} + void GSFrame::flip(draw_context_t) { ++m_frames; @@ -117,4 +117,4 @@ void GSFrame::flip(draw_context_t) m_frames = 0; fps_t.Start(); } -} \ No newline at end of file +} diff --git a/rpcs3/Gui/GSFrame.h b/rpcs3/Gui/GSFrame.h index 5c5db3de84..01aeea0130 100644 --- a/rpcs3/Gui/GSFrame.h +++ b/rpcs3/Gui/GSFrame.h @@ -1,10 +1,10 @@ -#pragma once -#include "Emu/Memory/vm.h" +#pragma once #include "Emu/RSX/GSRender.h" class GSFrame : public wxFrame, public GSFrameBase { u64 m_frames; + public: GSFrame(const wxString& title); @@ -27,6 +27,7 @@ protected: void set_current(draw_context_t context) override; void delete_context(void* context) override; void flip(draw_context_t context) override; + size2i client_size() override; public: void OnLeftDclick(wxMouseEvent&) diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 8486b2bd7d..e7ffab2305 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -423,27 +423,27 @@ void MainFrame::ConfigLLEModules(wxCommandEvent& event) void MainFrame::OpenELFCompiler(wxCommandEvent& WXUNUSED(event)) { - (new CompilerELF(this)) -> Show(); + (new CompilerELF(this))->Show(); } void MainFrame::OpenKernelExplorer(wxCommandEvent& WXUNUSED(event)) { - (new KernelExplorer(this)) -> Show(); + (new KernelExplorer(this))->Show(); } void MainFrame::OpenMemoryViewer(wxCommandEvent& WXUNUSED(event)) { - (new MemoryViewerPanel(this)) -> Show(); + (new MemoryViewerPanel(this))->Show(); } void MainFrame::OpenRSXDebugger(wxCommandEvent& WXUNUSED(event)) { - (new RSXDebugger(this)) -> Show(); + (new RSXDebugger(this))->Show(); } void MainFrame::OpenStringSearch(wxCommandEvent& WXUNUSED(event)) { - (new MemoryStringSearcher(this)) -> Show(); + (new MemoryStringSearcher(this))->Show(); } void MainFrame::OpenCgDisasm(wxCommandEvent& WXUNUSED(event)) diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 9e82fe5133..09bcd33be9 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -1,11 +1,13 @@ #include "stdafx_gui.h" + +#include "RSXDebugger.h" + #include "rpcs3/Ini.h" #include "Utilities/rPlatform.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "RSXDebugger.h" #include "Emu/SysCalls/Modules/cellVideoOut.h" #include "Emu/RSX/GSManager.h" #include "Emu/RSX/GSRender.h" @@ -296,7 +298,7 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event) { if (!RSXReady()) return; const GSRender& render = Emu.GetGSManager().GetRender(); - const auto buffers = vm::ps3::ptr::make(render.m_gcm_buffers_addr); + const auto buffers = render.gcm_buffers; if(!buffers) return; @@ -331,9 +333,9 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event) void RSXDebugger::GoToGet(wxCommandEvent& event) { if (!RSXReady()) return; - auto ctrl = vm::get_ptr(Emu.GetGSManager().GetRender().m_ctrlAddress); + //auto ctrl = vm::get_ptr(Emu.GetGSManager().GetRender().ctrlAddress); u32 realAddr; - if (RSXIOMem.getRealAddr(ctrl->get.load(), realAddr)) { + if (RSXIOMem.getRealAddr(0, realAddr)) { m_addr = realAddr; t_addr->SetValue(wxString::Format("%08x", m_addr)); UpdateInformation(); @@ -345,7 +347,7 @@ void RSXDebugger::GoToGet(wxCommandEvent& event) void RSXDebugger::GoToPut(wxCommandEvent& event) { if (!RSXReady()) return; - auto ctrl = vm::get_ptr(Emu.GetGSManager().GetRender().m_ctrlAddress); + auto ctrl = Emu.GetGSManager().GetRender().ctrl; u32 realAddr; if (RSXIOMem.getRealAddr(ctrl->put.load(), realAddr)) { m_addr = realAddr; @@ -410,10 +412,10 @@ void RSXDebugger::GetBuffers() // TODO: Currently it only supports color buffers for (u32 bufferId=0; bufferId < render.gcm_buffers_count; bufferId++) { - if(!vm::check_addr(render.m_gcm_buffers_addr)) + if(!vm::check_addr(render.gcm_buffers.addr())) continue; - auto buffers = vm::get_ptr(render.m_gcm_buffers_addr); + auto buffers = render.gcm_buffers; u32 RSXbuffer_addr = render.local_mem_addr + buffers[bufferId].offset; if(!vm::check_addr(RSXbuffer_addr)) @@ -492,25 +494,26 @@ void RSXDebugger::GetFlags() #define LIST_FLAGS_ADD(name, value) \ m_list_flags->InsertItem(i, name); m_list_flags->SetItem(i, 1, value ? "Enabled" : "Disabled"); i++; - - LIST_FLAGS_ADD("Alpha test", rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]); - LIST_FLAGS_ADD("Blend", rsx::method_registers[NV4097_SET_BLEND_ENABLE]); + /* + LIST_FLAGS_ADD("Alpha test", render.m_set_alpha_test); + LIST_FLAGS_ADD("Blend", render.m_set_blend); LIST_FLAGS_ADD("Scissor", render.m_set_scissor_horizontal && render.m_set_scissor_vertical); - LIST_FLAGS_ADD("Cull face", rsx::method_registers[NV4097_SET_CULL_FACE]); + LIST_FLAGS_ADD("Cull face", render.m_set_cull_face); LIST_FLAGS_ADD("Depth bounds test", render.m_set_depth_bounds_test); -// LIST_FLAGS_ADD("Depth test", render.m_set_depth_test); + LIST_FLAGS_ADD("Depth test", render.m_set_depth_test); LIST_FLAGS_ADD("Dither", render.m_set_dither); LIST_FLAGS_ADD("Line smooth", render.m_set_line_smooth); -// LIST_FLAGS_ADD("Logic op", render.m_set_logic_op); + LIST_FLAGS_ADD("Logic op", render.m_set_logic_op); LIST_FLAGS_ADD("Poly smooth", render.m_set_poly_smooth); LIST_FLAGS_ADD("Poly offset fill", render.m_set_poly_offset_fill); LIST_FLAGS_ADD("Poly offset line", render.m_set_poly_offset_line); LIST_FLAGS_ADD("Poly offset point", render.m_set_poly_offset_point); -// LIST_FLAGS_ADD("Stencil test", render.m_set_stencil_test); + LIST_FLAGS_ADD("Stencil test", render.m_set_stencil_test); LIST_FLAGS_ADD("Primitive restart", render.m_set_restart_index); LIST_FLAGS_ADD("Two sided lighting", render.m_set_two_side_light_enable); LIST_FLAGS_ADD("Point Sprite", render.m_set_point_sprite_control); LIST_FLAGS_ADD("Lighting ", render.m_set_specular); + */ #undef LIST_FLAGS_ADD } @@ -540,7 +543,7 @@ void RSXDebugger::GetLightning() #define LIST_LIGHTNING_ADD(name, value) \ m_list_lightning->InsertItem(i, name); m_list_lightning->SetItem(i, 1, value); i++; - LIST_LIGHTNING_ADD("Shade model", (render.m_shade_mode == 0x1D00) ? "Flat" : "Smooth"); + //LIST_LIGHTNING_ADD("Shade model", (render.m_shade_mode == 0x1D00) ? "Flat" : "Smooth"); #undef LIST_LIGHTNING_ADD } @@ -591,85 +594,87 @@ void RSXDebugger::GetSettings() #define LIST_SETTINGS_ADD(name, value) \ m_list_settings->InsertItem(i, name); m_list_settings->SetItem(i, 1, value); i++; - - LIST_SETTINGS_ADD("Alpha func", !(rsx::method_registers[NV4097_SET_ALPHA_FUNC]) ? "(none)" : wxString::Format("0x%x (%s)", - rsx::method_registers[NV4097_SET_ALPHA_FUNC], - ParseGCMEnum(rsx::method_registers[NV4097_SET_ALPHA_FUNC], CELL_GCM_ENUM))); - LIST_SETTINGS_ADD("Blend color", !(rsx::method_registers[NV4097_SET_BLEND_COLOR]) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d", - rsx::method_registers[NV4097_SET_BLEND_COLOR] & 0xFF, - (rsx::method_registers[NV4097_SET_BLEND_COLOR] >> 8) & 0xFF, - (rsx::method_registers[NV4097_SET_BLEND_COLOR] >> 16) & 0xFF, - (rsx::method_registers[NV4097_SET_BLEND_COLOR] >> 24) & 0xFF)); + /* + LIST_SETTINGS_ADD("Alpha func", !(render.m_set_alpha_func) ? "(none)" : wxString::Format("0x%x (%s)", + render.m_alpha_func, + ParseGCMEnum(render.m_alpha_func, CELL_GCM_ENUM))); + LIST_SETTINGS_ADD("Blend color", !(render.m_set_blend_color) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d", + render.m_blend_color_r, + render.m_blend_color_g, + render.m_blend_color_b, + render.m_blend_color_a)); LIST_SETTINGS_ADD("Clipping", wxString::Format("Min:%f, Max:%f", render.m_clip_min, render.m_clip_max)); - LIST_SETTINGS_ADD("Color mask", !(rsx::method_registers[NV4097_SET_COLOR_MASK]) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d", - (rsx::method_registers[NV4097_SET_COLOR_MASK] >> 16) & 0xff, - (rsx::method_registers[NV4097_SET_COLOR_MASK] >> 8) & 0xff, - (rsx::method_registers[NV4097_SET_COLOR_MASK]) & 0xff, - (rsx::method_registers[NV4097_SET_COLOR_MASK] >> 24) & 0xff)); - LIST_SETTINGS_ADD("Context DMA Color A", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_A])); - LIST_SETTINGS_ADD("Context DMA Color B", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_B])); - LIST_SETTINGS_ADD("Context DMA Color C", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_C])); - LIST_SETTINGS_ADD("Context DMA Color D", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_D])); - LIST_SETTINGS_ADD("Context DMA Zeta", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA])); + LIST_SETTINGS_ADD("Color mask", !(render.m_set_color_mask) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d", + render.m_color_mask_r, + render.m_color_mask_g, + render.m_color_mask_b, + render.m_color_mask_a)); + LIST_SETTINGS_ADD("Context DMA Color A", wxString::Format("0x%x", render.m_context_dma_color_a)); + LIST_SETTINGS_ADD("Context DMA Color B", wxString::Format("0x%x", render.m_context_dma_color_b)); + LIST_SETTINGS_ADD("Context DMA Color C", wxString::Format("0x%x", render.m_context_dma_color_c)); + LIST_SETTINGS_ADD("Context DMA Color D", wxString::Format("0x%x", render.m_context_dma_color_d)); + LIST_SETTINGS_ADD("Context DMA Zeta", wxString::Format("0x%x", render.m_context_dma_z)); LIST_SETTINGS_ADD("Depth bounds", wxString::Format("Min:%f, Max:%f", render.m_depth_bounds_min, render.m_depth_bounds_max)); -// LIST_SETTINGS_ADD("Depth func", !(render.m_set_depth_func) ? "(none)" : wxString::Format("0x%x (%s)", -// render.m_depth_func, -// ParseGCMEnum(render.m_depth_func, CELL_GCM_ENUM))); + LIST_SETTINGS_ADD("Depth func", !(render.m_set_depth_func) ? "(none)" : wxString::Format("0x%x (%s)", + render.m_depth_func, + ParseGCMEnum(render.m_depth_func, CELL_GCM_ENUM))); LIST_SETTINGS_ADD("Draw mode", wxString::Format("%d (%s)", - render.draw_mode, - ParseGCMEnum(render.draw_mode, CELL_GCM_PRIMITIVE_ENUM))); + render.m_draw_mode, + ParseGCMEnum(render.m_draw_mode, CELL_GCM_PRIMITIVE_ENUM))); LIST_SETTINGS_ADD("Scissor", wxString::Format("X:%d, Y:%d, W:%d, H:%d", render.m_scissor_x, render.m_scissor_y, render.m_scissor_w, render.m_scissor_h)); -// LIST_SETTINGS_ADD("Stencil func", !(render.m_set_stencil_func) ? "(none)" : wxString::Format("0x%x (%s)", -// render.m_stencil_func, -// ParseGCMEnum(render.m_stencil_func, CELL_GCM_ENUM))); - LIST_SETTINGS_ADD("Surface Pitch A", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_PITCH_A])); - LIST_SETTINGS_ADD("Surface Pitch B", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_PITCH_B])); - LIST_SETTINGS_ADD("Surface Pitch C", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_PITCH_C])); - LIST_SETTINGS_ADD("Surface Pitch D", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_PITCH_D])); - LIST_SETTINGS_ADD("Surface Pitch Z", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z])); - LIST_SETTINGS_ADD("Surface Offset A", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET])); - LIST_SETTINGS_ADD("Surface Offset B", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET])); - LIST_SETTINGS_ADD("Surface Offset C", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET])); - LIST_SETTINGS_ADD("Surface Offset D", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_COLOR_DOFFSET])); - LIST_SETTINGS_ADD("Surface Offset Z", wxString::Format("0x%x", rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET])); + LIST_SETTINGS_ADD("Stencil func", !(render.m_set_stencil_func) ? "(none)" : wxString::Format("0x%x (%s)", + render.m_stencil_func, + ParseGCMEnum(render.m_stencil_func, CELL_GCM_ENUM))); + LIST_SETTINGS_ADD("Surface Pitch A", wxString::Format("0x%x", render.m_surface_pitch_a)); + LIST_SETTINGS_ADD("Surface Pitch B", wxString::Format("0x%x", render.m_surface_pitch_b)); + LIST_SETTINGS_ADD("Surface Pitch C", wxString::Format("0x%x", render.m_surface_pitch_c)); + LIST_SETTINGS_ADD("Surface Pitch D", wxString::Format("0x%x", render.m_surface_pitch_d)); + LIST_SETTINGS_ADD("Surface Pitch Z", wxString::Format("0x%x", render.m_surface_pitch_z)); + LIST_SETTINGS_ADD("Surface Offset A", wxString::Format("0x%x", render.m_surface_offset_a)); + LIST_SETTINGS_ADD("Surface Offset B", wxString::Format("0x%x", render.m_surface_offset_b)); + LIST_SETTINGS_ADD("Surface Offset C", wxString::Format("0x%x", render.m_surface_offset_c)); + LIST_SETTINGS_ADD("Surface Offset D", wxString::Format("0x%x", render.m_surface_offset_d)); + LIST_SETTINGS_ADD("Surface Offset Z", wxString::Format("0x%x", render.m_surface_offset_z)); LIST_SETTINGS_ADD("Viewport", wxString::Format("X:%d, Y:%d, W:%d, H:%d", - rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] & 0xFFFF, - rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] & 0xFFFF, - rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16, - rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16)); - + render.m_viewport_x, + render.m_viewport_y, + render.m_viewport_w, + render.m_viewport_h)); + */ #undef LIST_SETTINGS_ADD } void RSXDebugger::SetFlags(wxListEvent& event) { + /* if (!RSXReady()) return; GSRender& render = Emu.GetGSManager().GetRender(); switch(event.m_itemIndex) { - case 0: rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE] ^= true; break; - case 1: rsx::method_registers[NV4097_SET_BLEND_ENABLE] ^= true; break; - case 2: rsx::method_registers[NV4097_SET_CULL_FACE] ^= true; break; + case 0: render.m_set_alpha_test ^= true; break; + case 1: render.m_set_blend ^= true; break; + case 2: render.m_set_cull_face ^= true; break; case 3: render.m_set_depth_bounds_test ^= true; break; -// case 4: render.m_set_depth_test ^= true; break; + case 4: render.m_set_depth_test ^= true; break; case 5: render.m_set_dither ^= true; break; case 6: render.m_set_line_smooth ^= true; break; -// case 7: render.m_set_logic_op ^= true; break; + case 7: render.m_set_logic_op ^= true; break; case 8: render.m_set_poly_smooth ^= true; break; case 9: render.m_set_poly_offset_fill ^= true; break; case 10: render.m_set_poly_offset_line ^= true; break; case 11: render.m_set_poly_offset_point ^= true; break; -// case 12: render.m_set_stencil_test ^= true; break; + case 12: render.m_set_stencil_test ^= true; break; case 13: render.m_set_point_sprite_control ^= true; break; case 14: render.m_set_restart_index ^= true; break; case 15: render.m_set_specular ^= true; break; case 16: render.m_set_scissor_horizontal ^= true; break; case 17: render.m_set_scissor_vertical ^= true; break; } + */ UpdateInformation(); } @@ -1206,4 +1211,4 @@ wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA bool RSXDebugger::RSXReady() { return Emu.GetGSManager().IsInited(); -} +} \ No newline at end of file diff --git a/rpcs3/Gui/RSXDebugger.h b/rpcs3/Gui/RSXDebugger.h index 733e552efb..7ba49b8deb 100644 --- a/rpcs3/Gui/RSXDebugger.h +++ b/rpcs3/Gui/RSXDebugger.h @@ -2,8 +2,6 @@ #include - - class RSXDebugger : public wxFrame { u32 m_addr; diff --git a/rpcs3/Gui/SettingsDialog.cpp b/rpcs3/Gui/SettingsDialog.cpp index f9762d9698..a2c8f74aaf 100644 --- a/rpcs3/Gui/SettingsDialog.cpp +++ b/rpcs3/Gui/SettingsDialog.cpp @@ -118,7 +118,8 @@ SettingsDialog::SettingsDialog(wxWindow *parent) wxCheckBox* chbox_gs_log_prog = new wxCheckBox(p_graphics, wxID_ANY, "Log shader programs"); wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(p_graphics, wxID_ANY, "Write Depth Buffer"); wxCheckBox* chbox_gs_dump_color = new wxCheckBox(p_graphics, wxID_ANY, "Write Color Buffers"); - wxCheckBox* chbox_gs_read_color = new wxCheckBox(p_graphics, wxID_ANY, "Read Color Buffer"); + wxCheckBox* chbox_gs_read_color = new wxCheckBox(p_graphics, wxID_ANY, "Read Color Buffers"); + wxCheckBox* chbox_gs_read_depth = new wxCheckBox(p_graphics, wxID_ANY, "Read Depth Buffer"); wxCheckBox* chbox_gs_vsync = new wxCheckBox(p_graphics, wxID_ANY, "VSync"); wxCheckBox* chbox_gs_debug_output = new wxCheckBox(p_graphics, wxID_ANY, "Debug Output"); wxCheckBox* chbox_gs_3dmonitor = new wxCheckBox(p_graphics, wxID_ANY, "3D Monitor"); @@ -256,7 +257,8 @@ SettingsDialog::SettingsDialog(wxWindow *parent) chbox_gs_log_prog->SetValue(Ini.GSLogPrograms.GetValue()); chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue()); chbox_gs_dump_color->SetValue(Ini.GSDumpColorBuffers.GetValue()); - chbox_gs_read_color->SetValue(Ini.GSReadColorBuffer.GetValue()); + chbox_gs_read_color->SetValue(Ini.GSReadColorBuffers.GetValue()); + chbox_gs_read_depth->SetValue(Ini.GSReadDepthBuffer.GetValue()); chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue()); chbox_gs_debug_output->SetValue(Ini.GSDebugOutputEnable.GetValue()); chbox_gs_3dmonitor->SetValue(Ini.GS3DTV.GetValue()); @@ -346,9 +348,10 @@ SettingsDialog::SettingsDialog(wxWindow *parent) s_subpanel_graphics1->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(s_round_gs_d3d_adaptater, wxSizerFlags().Border(wxALL, 5).Expand()); - s_subpanel_graphics1->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(chbox_gs_read_color, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel_graphics1->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel_graphics1->Add(chbox_gs_read_depth, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics1->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics2->Add(s_round_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_graphics2->Add(s_round_gs_frame_limit, wxSizerFlags().Border(wxALL, 5).Expand()); @@ -437,7 +440,8 @@ SettingsDialog::SettingsDialog(wxWindow *parent) Ini.GSLogPrograms.SetValue(chbox_gs_log_prog->GetValue()); Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue()); Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue()); - Ini.GSReadColorBuffer.SetValue(chbox_gs_read_color->GetValue()); + Ini.GSReadColorBuffers.SetValue(chbox_gs_read_color->GetValue()); + Ini.GSReadDepthBuffer.SetValue(chbox_gs_read_depth->GetValue()); Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue()); Ini.GSDebugOutputEnable.SetValue(chbox_gs_debug_output->GetValue()); Ini.GS3DTV.SetValue(chbox_gs_3dmonitor->GetValue()); diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index f1b56aadb9..197de5936d 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -111,7 +111,8 @@ public: IniEntry GSLogPrograms; IniEntry GSDumpColorBuffers; IniEntry GSDumpDepthBuffer; - IniEntry GSReadColorBuffer; + IniEntry GSReadColorBuffers; + IniEntry GSReadDepthBuffer; IniEntry GSVSyncEnable; IniEntry GS3DTV; IniEntry GSDebugOutputEnable; @@ -202,16 +203,17 @@ public: GSLogPrograms.Init("GS_LogPrograms", path); GSDumpColorBuffers.Init("GS_DumpColorBuffers", path); GSDumpDepthBuffer.Init("GS_DumpDepthBuffer", path); - GSReadColorBuffer.Init("GS_GSReadColorBuffer", path); + GSReadColorBuffers.Init("GS_ReadColorBuffer", path); + GSReadDepthBuffer.Init("GS_ReadDepthBuffer", path); GSVSyncEnable.Init("GS_VSyncEnable", path); GSDebugOutputEnable.Init("GS_DebugOutputEnable", path); GS3DTV.Init("GS_3DTV", path); GSOverlay.Init("GS_Overlay", path); // Audio - AudioOutMode.Init("Audio_AudioOutMode", path); - AudioDumpToFile.Init("Audio_AudioDumpToFile", path); - AudioConvertToU16.Init("Audio_AudioConvertToU16", path); + AudioOutMode.Init("Audio_OutMode", path); + AudioDumpToFile.Init("Audio_DumpToFile", path); + AudioConvertToU16.Init("Audio_ConvertToU16", path); // Camera Camera.Init("Camera", path); @@ -289,7 +291,8 @@ public: GSLogPrograms.Load(false); GSDumpColorBuffers.Load(false); GSDumpDepthBuffer.Load(false); - GSReadColorBuffer.Load(false); + GSReadColorBuffers.Load(false); + GSReadDepthBuffer.Load(false); GSVSyncEnable.Load(false); GSDebugOutputEnable.Load(false); GS3DTV.Load(false); @@ -376,7 +379,8 @@ public: GSLogPrograms.Save(); GSDumpColorBuffers.Save(); GSDumpDepthBuffer.Save(); - GSReadColorBuffer.Save(); + GSReadColorBuffers.Save(); + GSReadDepthBuffer.Save(); GSVSyncEnable.Save(); GSDebugOutputEnable.Save(); GS3DTV.Save(); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 0ee67bc0a2..9363293a30 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -76,6 +76,8 @@ + + @@ -557,6 +559,7 @@ + @@ -834,8 +837,7 @@ stdafx.h Async true - - + ../glm false @@ -852,8 +854,7 @@ stdafx.h Async true - - + ../glm false @@ -870,8 +871,7 @@ stdafx.h Async true - - + ../glm true @@ -891,8 +891,7 @@ stdafx.h Async true - - + ../glm true @@ -912,8 +911,7 @@ stdafx.h Async true - - + ../glm true @@ -930,8 +928,7 @@ stdafx.h Async true - - + ../glm _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -951,8 +948,7 @@ stdafx.h Async true - - + ../glm _UNICODE;UNICODE;DX12_SUPPORT;%(PreprocessorDefinitions) false @@ -974,8 +970,7 @@ Async LLVM_AVAILABLE;%(PreprocessorDefinitions) true - - + ../glm true @@ -999,8 +994,7 @@ Async LLVM_AVAILABLE;DX12_SUPPORT;%(PreprocessorDefinitions) true - - + ../glm false diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 0f90e5604e..e75f69456f 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -995,6 +995,12 @@ Emu\GPU\RSX\Common + + Emu\GPU\RSX\Null + + + Emu\GPU\RSX\GL + @@ -1897,5 +1903,8 @@ Utilities + + Emu\GPU\RSX\GL + \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 12224c80d4..dc859edf72 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -206,7 +206,7 @@ Disabled ProgramDatabase Use - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm Async stdafx_gui.h $(IntDir)$(TargetName)_gui.pch @@ -236,7 +236,7 @@ Disabled ProgramDatabase Use - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm Async stdafx_gui.h $(IntDir)$(TargetName)_gui.pch @@ -266,7 +266,7 @@ Disabled ProgramDatabase Use - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm Async stdafx_gui.h $(IntDir)$(TargetName)_gui.pch @@ -296,7 +296,7 @@ Disabled ProgramDatabase Use - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm Async stdafx_gui.h $(IntDir)$(TargetName)_gui.pch @@ -326,7 +326,7 @@ Disabled ProgramDatabase Use - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm _UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions);DX12_SUPPORT Async stdafx_gui.h @@ -356,7 +356,7 @@ Full true true - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm MultiThreadedDLL WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) false @@ -394,7 +394,7 @@ Full true true - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm MultiThreadedDLL WIN32;NDEBUG;_WINDOWS;LLVM_AVAILABLE;%(PreprocessorDefinitions) false @@ -432,7 +432,7 @@ Full true true - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm MultiThreadedDLL WIN32;NDEBUG;_WINDOWS;DX12_SUPPORT;%(PreprocessorDefinitions) false @@ -471,7 +471,7 @@ Full true true - ..\wxWidgets\include\msvc + ..\wxWidgets\include\msvc;..\glm MultiThreadedDLL WIN32;NDEBUG;_WINDOWS;LLVM_AVAILABLE;DX12_SUPPORT;%(PreprocessorDefinitions) false