bool GSWndEGL::Create(const string& title, int w, int h) { if(m_NativeWindow) throw GSDXRecoverableError(); if(w <= 0 || h <= 0) { w = theApp.GetConfig("ModeWidth", 640); h = theApp.GetConfig("ModeHeight", 480); } m_managed = true; // note this part must be only executed when replaying .gs debug file m_NativeDisplay = XOpenDisplay(NULL); OpenEGLDisplay(); m_NativeWindow = XCreateSimpleWindow(m_NativeDisplay, DefaultRootWindow(m_NativeDisplay), 0, 0, w, h, 0, 0, 0); XMapWindow (m_NativeDisplay, m_NativeWindow); CreateContext(3, 3); AttachContext(); CheckContext(); PopulateGlFunction(); if (m_NativeWindow == 0) throw GSDXRecoverableError(); return true; }
void GSDevice11::CompileShader(const char* source, size_t size, const char *fn, ID3DInclude *include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11ComputeShader** cs) { HRESULT hr; vector<D3D_SHADER_MACRO> m; PrepareShaderMacro(m, macro); CComPtr<ID3DBlob> shader, error; hr = s_pD3DCompile(source, size, fn, &m[0], s_old_d3d_compiler_dll ? nullptr : include, entry, m_shader.cs.c_str(), 0, 0, &shader, &error); if(error) { printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateComputeShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), NULL, cs); if(FAILED(hr)) { throw GSDXRecoverableError(); } }
void GSDevice11::CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11GeometryShader** gs, D3D11_SO_DECLARATION_ENTRY* layout, int count) { HRESULT hr; vector<D3D11_SHADER_MACRO> m; PrepareShaderMacro(m, macro); CComPtr<ID3D11Blob> shader, error; hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry, m_shader.gs.c_str(), 0, 0, NULL, &shader, &error, NULL); if(error) { printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateGeometryShaderWithStreamOutput((void*)shader->GetBufferPointer(), shader->GetBufferSize(), layout, count, NULL, 0, D3D11_SO_NO_RASTERIZED_STREAM, NULL, gs); if(FAILED(hr)) { throw GSDXRecoverableError(); } }
void GSDevice11::CompileShader(const char* fn, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11ComputeShader** cs) { HRESULT hr; vector<D3D11_SHADER_MACRO> m; PrepareShaderMacro(m, macro); CComPtr<ID3D11Blob> shader, error; hr = D3DX11CompileFromFile(fn, &m[0], NULL, entry, m_shader.cs.c_str(), 0, 0, NULL, &shader, &error, NULL); if(error) { printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateComputeShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(),NULL, cs); if(FAILED(hr)) { throw GSDXRecoverableError(); } }
void GSDevice11::CompileShader(const char* source, size_t size, const char* fn, ID3DInclude *include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11GeometryShader** gs, D3D11_SO_DECLARATION_ENTRY* layout, int count) { HRESULT hr; vector<D3D_SHADER_MACRO> m; PrepareShaderMacro(m, macro); CComPtr<ID3DBlob> shader, error; hr = s_pD3DCompile(source, size, fn, &m[0], s_old_d3d_compiler_dll ? nullptr : include, entry, m_shader.gs.c_str(), 0, 0, &shader, &error); if(error) { printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateGeometryShaderWithStreamOutput((void*)shader->GetBufferPointer(), shader->GetBufferSize(), layout, count, NULL, 0, D3D11_SO_NO_RASTERIZED_STREAM, NULL, gs); if(FAILED(hr)) { throw GSDXRecoverableError(); } }
void GSDevice11::CompileShader(uint32 id, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11PixelShader** ps) { HRESULT hr; vector<D3D11_SHADER_MACRO> m; PrepareShaderMacro(m, macro); CComPtr<ID3D11Blob> shader, error; hr = D3DX11CompileFromResource(theApp.GetModuleHandle(), MAKEINTRESOURCE(id), NULL, &m[0], NULL, entry, m_shader.ps.c_str(), 0, 0, NULL, &shader, &error, NULL); if(error) { printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreatePixelShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(),NULL, ps); if(FAILED(hr)) { throw GSDXRecoverableError(); } }
bool GSWndOGL::Create(const string& title, int w, int h) { if(m_NativeWindow) throw GSDXRecoverableError(); if(w <= 0 || h <= 0) { w = theApp.GetConfig("ModeWidth", 640); h = theApp.GetConfig("ModeHeight", 480); } m_managed = true; // note this part must be only executed when replaying .gs debug file m_NativeDisplay = XOpenDisplay(NULL); m_NativeWindow = XCreateSimpleWindow(m_NativeDisplay, DefaultRootWindow(m_NativeDisplay), 0, 0, w, h, 0, 0, 0); XMapWindow (m_NativeDisplay, m_NativeWindow); if (m_NativeWindow == 0) throw GSDXRecoverableError(); CreateContext(3, 3); AttachContext(); CheckContext(); m_swapinterval = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalEXT"); PopulateGlFunction(); return true; }
void GSWndEGL::OpenEGLDisplay() { // Create an EGL display from the native display m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_NativeDisplay); if ( m_eglDisplay == EGL_NO_DISPLAY ) throw GSDXRecoverableError(); if ( !eglInitialize(m_eglDisplay, NULL, NULL) ) throw GSDXRecoverableError(); }
void GSWndEGL::OpenEGLDisplay() { // Create an EGL display from the native display m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_NativeDisplay); if ( m_eglDisplay == EGL_NO_DISPLAY ) { fprintf(stderr,"EGL: Failed to open a display! (0x%x)\n", eglGetError() ); throw GSDXRecoverableError(); } if ( !eglInitialize(m_eglDisplay, NULL, NULL) ) { fprintf(stderr,"EGL: Failed to initialize the display! (0x%x)\n", eglGetError() ); throw GSDXRecoverableError(); } }
void* GSWndOGL::GetProcAddress(const char* name, bool opt) { void* ptr = (void*)glXGetProcAddress((const GLubyte*)name); if (ptr == NULL) { fprintf(stderr, "Failed to find %s\n", name); if (!opt) throw GSDXRecoverableError(); } return ptr; }
void GSWndOGL::CheckContext() { int glxMajorVersion, glxMinorVersion; glXQueryVersion(m_NativeDisplay, &glxMajorVersion, &glxMinorVersion); if (glXIsDirect(m_NativeDisplay, m_context)) fprintf(stdout, "glX-Version %d.%d with Direct Rendering\n", glxMajorVersion, glxMinorVersion); else { fprintf(stderr, "glX-Version %d.%d with Indirect Rendering !!! It won't support properly opengl\n", glxMajorVersion, glxMinorVersion); throw GSDXRecoverableError(); } }
static void win_error(const char* msg, bool fatal = true) { DWORD errorID = ::GetLastError(); if (errorID) fprintf(stderr, "WIN API ERROR:%ld\t", errorID); if (fatal) { MessageBox(NULL, msg, "ERROR", MB_OK | MB_ICONEXCLAMATION); throw GSDXRecoverableError(); } else { fprintf(stderr, "ERROR:%s\n", msg); } }
void GSDevice11::CompileShader(const char* source, size_t size, const char* fn, ID3DInclude *include, const char* entry, D3D_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il) { HRESULT hr; vector<D3D_SHADER_MACRO> m; PrepareShaderMacro(m, macro); CComPtr<ID3DBlob> shader, error; hr = s_pD3DCompile(source, size, fn, &m[0], s_old_d3d_compiler_dll? nullptr : include, entry, m_shader.vs.c_str(), 0, 0, &shader, &error); if(error) { printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateVertexShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), NULL, vs); if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateInputLayout(layout, count, shader->GetBufferPointer(), shader->GetBufferSize(), il); if(FAILED(hr)) { throw GSDXRecoverableError(); } }
void GSDevice11::CompileShader(const char* fn, const char* entry, D3D11_SHADER_MACRO* macro, ID3D11VertexShader** vs, D3D11_INPUT_ELEMENT_DESC* layout, int count, ID3D11InputLayout** il) { HRESULT hr; vector<D3D11_SHADER_MACRO> m; PrepareShaderMacro(m, macro); CComPtr<ID3D11Blob> shader, error; hr = D3DX11CompileFromFile(fn, &m[0], NULL, entry, m_shader.vs.c_str(), 0, 0, NULL, &shader, &error, NULL); if(error) { printf("%s\n", (const char*)error->GetBufferPointer()); } if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateVertexShader((void*)shader->GetBufferPointer(), shader->GetBufferSize(), NULL, vs); if(FAILED(hr)) { throw GSDXRecoverableError(); } hr = m_dev->CreateInputLayout(layout, count, shader->GetBufferPointer(), shader->GetBufferSize(), il); if(FAILED(hr)) { throw GSDXRecoverableError(); } }
void GSDevice11::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor) { ID3D11RenderTargetView* rtv = NULL; ID3D11DepthStencilView* dsv = NULL; if (!rt && !ds) throw GSDXRecoverableError(); if(rt) rtv = *(GSTexture11*)rt; if(ds) dsv = *(GSTexture11*)ds; if(m_state.rtv != rtv || m_state.dsv != dsv) { m_state.rtv = rtv; m_state.dsv = dsv; m_ctx->OMSetRenderTargets(1, &rtv, dsv); } GSVector2i size = rt ? rt->GetSize() : ds->GetSize(); if(m_state.viewport != size) { bool isNative = theApp.GetConfig("upscale_multiplier", 1) == 1; m_state.viewport = size; D3D11_VIEWPORT vp; memset(&vp, 0, sizeof(vp)); vp.TopLeftX = (spritehack > 0 || isNative) ? 0.0f : -0.01f; vp.TopLeftY = (spritehack > 0 || isNative) ? 0.0f : -0.01f; vp.Width = (float)size.x; vp.Height = (float)size.y; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; m_ctx->RSSetViewports(1, &vp); } GSVector4i r = scissor ? *scissor : GSVector4i(size).zwxy(); if(!m_state.scissor.eq(r)) { m_state.scissor = r; m_ctx->RSSetScissorRects(1, r); } }
void GSWndOGL::CreateContext(int major, int minor) { if ( !m_NativeDisplay || !m_NativeWindow ) { fprintf( stderr, "Wrong X11 display/window\n" ); throw GSDXRecoverableError(); } // Get visual information static int attrListDbl[] = { // GLX_X_RENDERABLE: If True is specified, then only frame buffer configurations that have associated X // visuals (and can be used to render to Windows and/or GLX pixmaps) will be considered. The default value is GLX_DONT_CARE. GLX_X_RENDERABLE , True, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_DOUBLEBUFFER , True, None }; PFNGLXCHOOSEFBCONFIGPROC glX_ChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) glXGetProcAddress((GLubyte *) "glXChooseFBConfig"); int fbcount = 0; GLXFBConfig *fbc = glX_ChooseFBConfig(m_NativeDisplay, DefaultScreen(m_NativeDisplay), attrListDbl, &fbcount); if (!fbc || fbcount < 1) { throw GSDXRecoverableError(); } PFNGLXCREATECONTEXTATTRIBSARBPROC glX_CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); if (!glX_CreateContextAttribsARB) { throw GSDXRecoverableError(); } // Install a dummy handler to handle gracefully (aka not segfault) the support of GL version int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); // Be sure the handler is installed XSync( m_NativeDisplay, false); // Create a context int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major, GLX_CONTEXT_MINOR_VERSION_ARB, minor, #ifdef ENABLE_OGL_DEBUG GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, #endif GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, None }; m_context = glX_CreateContextAttribsARB(m_NativeDisplay, fbc[0], 0, true, context_attribs); XFree(fbc); // Don't forget to reinstall the older Handler XSetErrorHandler(oldHandler); // Get latest error XSync( m_NativeDisplay, false); if (!m_context || ctxError) { fprintf(stderr, "Failed to create the opengl context. Check your drivers support openGL %d.%d. Hint: opensource drivers don't\n", major, minor ); throw GSDXRecoverableError(); } }
void GSWndEGL::CreateContext(int major, int minor) { EGLConfig eglConfig; EGLint numConfigs = 0; EGLint contextAttribs[] = { EGL_CONTEXT_MAJOR_VERSION_KHR, major, EGL_CONTEXT_MINOR_VERSION_KHR, minor, #ifndef ENABLE_GLES #ifdef ENABLE_OGL_DEBUG EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, #endif EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR, #endif EGL_NONE }; EGLint NullContextAttribs[] = { EGL_NONE }; EGLint attrList[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 24, #ifndef ENABLE_GLES EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, #endif EGL_NONE }; #ifndef ENABLE_GLES eglBindAPI(EGL_OPENGL_API); #endif eglChooseConfig(m_eglDisplay, attrList, &eglConfig, 1, &numConfigs); if ( numConfigs == 0 ) { fprintf(stderr,"EGL: Failed to get a frame buffer config!\n"); throw GSDXRecoverableError(); } m_eglSurface = eglCreateWindowSurface(m_eglDisplay, eglConfig, m_NativeWindow, NULL); if ( m_eglSurface == EGL_NO_SURFACE ) { fprintf(stderr,"EGL: Failed to get a window surface\n"); throw GSDXRecoverableError(); } m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs); EGLint status = eglGetError(); if (status == EGL_BAD_ATTRIBUTE || status == EGL_BAD_MATCH) { // Radeon/Gallium don't support advance attribute. Fallback to random value // Note: Intel gives an EGL_BAD_MATCH. I don't know why but let's by stubborn and retry. fprintf(stderr, "EGL: warning your driver doesn't suport advance openGL context attributes\n"); m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, NullContextAttribs); status = eglGetError(); } if ( m_eglContext == EGL_NO_CONTEXT ) { fprintf(stderr,"EGL: Failed to create the context\n"); fprintf(stderr,"EGL STATUS: %x\n", status); throw GSDXRecoverableError(); } if ( !eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext) ) { throw GSDXRecoverableError(); } }