struct GalliumDXGISwapChain;
struct GalliumDXGIFactory;
-static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** ppSwapChain);
-static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* adapter, const struct native_platform* platform, void* dpy, IDXGIAdapter1** ppAdapter);
-static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** ppOutput);
+static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain);
+static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* adapter, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter);
+static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output);
static void GalliumDXGISwapChainRevalidate(IDXGISwapChain* swap_chain);
template<typename Base = IDXGIObject, typename Parent = IDXGIObject>
this->parent = p_parent;
}
- virtual HRESULT STDMETHODCALLTYPE GetParent(
- __in REFIID riid,
- __out void **ppParent)
- {
- return parent->QueryInterface(riid, ppParent);
- }
+ virtual HRESULT STDMETHODCALLTYPE GetParent(
+ REFIID riid,
+ void **out_parent)
+ {
+ return parent->QueryInterface(riid, out_parent);
+ }
};
COM_INTERFACE(IGalliumDXGIBackend, IUnknown)
+// TODO: somehow check whether the window is fully obscured or not
struct GalliumDXGIIdentityBackend : public GalliumComObject<IGalliumDXGIBackend>
{
- virtual void * STDMETHODCALLTYPE BeginPresent(
+ virtual HRESULT STDMETHODCALLTYPE BeginPresent(
HWND hwnd,
+ void** present_cookie,
void** window,
RECT *rect,
RGNDATA **rgndata,
// yes, because we like things looking good
*preserve_aspect_ratio = TRUE;
- return 0;
+ *present_cookie = 0;
+ return S_OK;
}
virtual void STDMETHODCALLTYPE EndPresent(
void* present_cookie
)
{}
+
+ virtual HRESULT STDMETHODCALLTYPE TestPresent(HWND hwnd)
+ {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE GetPresentSize(
+ HWND hwnd,
+ unsigned* width,
+ unsigned* height
+ )
+ {
+ *width = 0;
+ *height = 0;
+ return S_OK;
+ }
+};
+
+// TODO: maybe install an X11 error hook, so we can return errors properly
+struct GalliumDXGIX11IdentityBackend : public GalliumDXGIIdentityBackend
+{
+ Display* dpy;
+
+ GalliumDXGIX11IdentityBackend(Display* dpy)
+ : dpy(dpy)
+ {}
+
+ virtual HRESULT STDMETHODCALLTYPE GetPresentSize(
+ HWND hwnd,
+ unsigned* width,
+ unsigned* height
+ )
+ {
+ XWindowAttributes xwa;
+ XGetWindowAttributes(dpy, (Window)hwnd, &xwa);
+ *width = xwa.width;
+ *height = xwa.height;
+ return S_OK;
+ }
};
struct GalliumDXGIFactory : public GalliumDXGIObject<IDXGIFactory1, IUnknown>
{
- HWND associated_window;
+ HWND associated_window;
const struct native_platform* platform;
void* display;
ComPtr<IGalliumDXGIBackend> backend;
GalliumDXGIFactory(const struct native_platform* platform, void* display, IGalliumDXGIBackend* p_backend)
: GalliumDXGIObject<IDXGIFactory1, IUnknown>((IUnknown*)NULL), platform(platform), display(display)
- {
+ {
if(p_backend)
backend = p_backend;
+ else if(!strcmp(platform->name, "X11"))
+ backend.reset(new GalliumDXGIX11IdentityBackend((Display*)display));
else
backend.reset(new GalliumDXGIIdentityBackend());
}
- virtual HRESULT STDMETHODCALLTYPE EnumAdapters(
- UINT Adapter,
- __out IDXGIAdapter **ppAdapter)
+ virtual HRESULT STDMETHODCALLTYPE EnumAdapters(
+ UINT adapter,
+ IDXGIAdapter **out_adapter)
{
- return EnumAdapters1(Adapter, (IDXGIAdapter1**)ppAdapter);
+ return EnumAdapters1(adapter, (IDXGIAdapter1**)out_adapter);
}
- virtual HRESULT STDMETHODCALLTYPE EnumAdapters1(
- UINT Adapter,
- __out IDXGIAdapter1 **ppAdapter)
- {
- *ppAdapter = 0;
- if(Adapter == 0)
+ virtual HRESULT STDMETHODCALLTYPE EnumAdapters1(
+ UINT adapter,
+ IDXGIAdapter1 **out_adapter)
+ {
+ *out_adapter = 0;
+ if(adapter == 0)
{
- return GalliumDXGIAdapterCreate(this, platform, display, ppAdapter);
+ return GalliumDXGIAdapterCreate(this, platform, display, out_adapter);
}
#if 0
// TODO: enable this
- if(platform == native_get_x11_platform())
- {
- unsigned nscreens = ScreenCount((Display*)display);
- if(Adapter < nscreens)
- {
- unsigned def_screen = DefaultScreen(display);
- if(Adapter <= def_screen)
- --Adapter;
- *ppAdapter = GalliumDXGIAdapterCreate(this, platform, display, Adapter);
- return S_OK;
- }
- }
+ if(platform == native_get_x11_platform())
+ {
+ unsigned nscreens = ScreenCount((Display*)display);
+ if(adapter < nscreens)
+ {
+ unsigned def_screen = DefaultScreen(display);
+ if(adapter <= def_screen)
+ --adapter;
+ *out_adapter = GalliumDXGIAdapterCreate(this, platform, display, adapter);
+ return S_OK;
+ }
+ }
#endif
return DXGI_ERROR_NOT_FOUND;
- }
+ }
- /* TODO: this is a mysterious underdocumented magic API
- * Can we have multiple windows associated?
- * Can we have multiple windows associated if we use multiple factories?
- * If so, what should GetWindowAssociation return?
- * If not, does a new swapchain steal the association?
- * Does this act for existing swapchains? For new swapchains?
- */
- virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(
- HWND WindowHandle,
- UINT Flags)
- {
- /* TODO: actually implement, for Wine, X11 and KMS*/
- associated_window = WindowHandle;
- return S_OK;
- }
+ /* TODO: this is a mysterious underdocumented magic API
+ * Can we have multiple windows associated?
+ * Can we have multiple windows associated if we use multiple factories?
+ * If so, what should GetWindowAssociation return?
+ * If not, does a new swapchain steal the association?
+ * Does this act for existing swapchains? For new swapchains?
+ */
+ virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(
+ HWND window_handle,
+ UINT flags)
+ {
+ /* TODO: actually implement, for Wine, X11 and KMS*/
+ associated_window = window_handle;
+ return S_OK;
+ }
- virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation(
- __out HWND *pWindowHandle)
- {
- *pWindowHandle = associated_window;
- return S_OK;
- }
+ virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation(
+ HWND *pwindow_handle)
+ {
+ *pwindow_handle = associated_window;
+ return S_OK;
+ }
- virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(
- __in IUnknown *pDevice,
- __in DXGI_SWAP_CHAIN_DESC *pDesc,
- __out IDXGISwapChain **ppSwapChain)
- {
- return GalliumDXGISwapChainCreate(this, pDevice, *pDesc, ppSwapChain);
- }
+ virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(
+ IUnknown *device,
+ DXGI_SWAP_CHAIN_DESC *desc,
+ IDXGISwapChain **out_swap_chain)
+ {
+ return GalliumDXGISwapChainCreate(this, device, *desc, out_swap_chain);
+ }
- virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter(
- HMODULE Module,
- __out IDXGIAdapter **ppAdapter)
- {
- /* TODO: ignore the module, and just create a Gallium software screen */
- *ppAdapter = 0;
- return E_NOTIMPL;
- }
+ virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter(
+ HMODULE module,
+ IDXGIAdapter **out_adapter)
+ {
+ /* TODO: ignore the module, and just create a Gallium software screen */
+ *out_adapter = 0;
+ return E_NOTIMPL;
+ }
- /* TODO: support hotplug */
- virtual BOOL STDMETHODCALLTYPE IsCurrent( void)
- {
- return TRUE;
- }
+ /* TODO: support hotplug */
+ virtual BOOL STDMETHODCALLTYPE IsCurrent( void)
+ {
+ return TRUE;
+ }
};
struct GalliumDXGIAdapter
: public GalliumMultiComObject<
- GalliumDXGIObject<IDXGIAdapter1, GalliumDXGIFactory>,
- IGalliumAdapter>
+ GalliumDXGIObject<IDXGIAdapter1, GalliumDXGIFactory>,
+ IGalliumAdapter>
{
struct native_display* display;
const struct native_config** configs;
{
this->parent = factory;
+ /* FIXME handler should be static */
handler.invalid_surface = handle_invalid_surface;
handler.new_drm_screen = dxgi_loader_create_drm_screen;
handler.new_sw_screen = dxgi_loader_create_sw_screen;
- display = platform->create_display(dpy, &handler, this);
+ platform->set_event_handler(&handler);
+
+ display = platform->create_display(dpy, FALSE, this);
if(!display)
+ display = platform->create_display(dpy, TRUE, this);
+ if(!display)
throw E_FAIL;
memset(&desc, 0, sizeof(desc));
std::string s = std::string("GalliumD3D on ") + display->screen->get_name(display->screen) + " by " + display->screen->get_vendor(display->screen);
free(connectors);
}
- virtual HRESULT STDMETHODCALLTYPE EnumOutputs(
- UINT Output,
- __out IDXGIOutput **ppOutput)
+ virtual HRESULT STDMETHODCALLTYPE EnumOutputs(
+ UINT output,
+ IDXGIOutput **out_output)
{
- if(Output >= (unsigned)num_outputs)
- return DXGI_ERROR_NOT_FOUND;
-
- if(connectors)
- {
- std::ostringstream ss;
- ss << "Output #" << Output;
- return GalliumDXGIOutputCreate(this, ss.str(), connectors[Output], ppOutput);
- }
- else
- return GalliumDXGIOutputCreate(this, "Unique output", NULL, ppOutput);
+ if(output >= (unsigned)num_outputs)
+ return DXGI_ERROR_NOT_FOUND;
+
+ if(connectors)
+ {
+ std::ostringstream ss;
+ ss << "output #" << output;
+ return GalliumDXGIOutputCreate(this, ss.str(), connectors[output], out_output);
+ }
+ else
+ return GalliumDXGIOutputCreate(this, "Unique output", NULL, out_output);
}
- virtual HRESULT STDMETHODCALLTYPE GetDesc(
- __out DXGI_ADAPTER_DESC *pDesc)
- {
- memcpy(pDesc, &desc, sizeof(*pDesc));
- return S_OK;
- }
+ virtual HRESULT STDMETHODCALLTYPE GetDesc(
+ DXGI_ADAPTER_DESC *desc)
+ {
+ memcpy(desc, &desc, sizeof(*desc));
+ return S_OK;
+ }
- virtual HRESULT STDMETHODCALLTYPE GetDesc1(
- __out DXGI_ADAPTER_DESC1 *pDesc)
- {
- memcpy(pDesc, &desc, sizeof(*pDesc));
- return S_OK;
- }
+ virtual HRESULT STDMETHODCALLTYPE GetDesc1(
+ DXGI_ADAPTER_DESC1 *desc)
+ {
+ memcpy(desc, &desc, sizeof(*desc));
+ return S_OK;
+ }
- virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport(
- __in REFGUID InterfaceName,
- __out LARGE_INTEGER *pUMDVersion)
- {
- // these number was taken from Windows 7 with Catalyst 10.8: its meaning is unclear
- if(InterfaceName == IID_ID3D11Device || InterfaceName == IID_ID3D10Device1 || InterfaceName == IID_ID3D10Device)
- {
- pUMDVersion->QuadPart = 0x00080011000a0411ULL;
- return S_OK;
- }
- return DXGI_ERROR_UNSUPPORTED;
- }
+ virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport(
+ REFGUID interface_name,
+ LARGE_INTEGER *u_m_d_version)
+ {
+ // these number was taken from Windows 7 with Catalyst 10.8: its meaning is unclear
+ if(interface_name == IID_ID3D11Device || interface_name == IID_ID3D10Device1 || interface_name == IID_ID3D10Device)
+ {
+ u_m_d_version->QuadPart = 0x00080011000a0411ULL;
+ return S_OK;
+ }
+ return DXGI_ERROR_UNSUPPORTED;
+ }
- pipe_screen* STDMETHODCALLTYPE GetGalliumScreen()
- {
- return display->screen;
- }
+ pipe_screen* STDMETHODCALLTYPE GetGalliumScreen()
+ {
+ return display->screen;
+ }
- pipe_screen* STDMETHODCALLTYPE GetGalliumReferenceSoftwareScreen()
- {
- // TODO: give a softpipe screen
- return display->screen;
- }
+ pipe_screen* STDMETHODCALLTYPE GetGalliumReferenceSoftwareScreen()
+ {
+ // TODO: give a softpipe screen
+ return display->screen;
+ }
- pipe_screen* STDMETHODCALLTYPE GetGalliumFastSoftwareScreen()
+ pipe_screen* STDMETHODCALLTYPE GetGalliumFastSoftwareScreen()
{
// TODO: give an llvmpipe screen
return display->screen;
}
virtual HRESULT STDMETHODCALLTYPE GetDesc(
- __out DXGI_OUTPUT_DESC *pDesc)
+ DXGI_OUTPUT_DESC *out_desc)
{
- *pDesc = desc;
+ *out_desc = desc;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList(
- DXGI_FORMAT EnumFormat,
- UINT Flags,
- __inout UINT *pNumModes,
- __out_ecount_part_opt(*pNumModes,*pNumModes) DXGI_MODE_DESC *pDesc)
+ DXGI_FORMAT enum_format,
+ UINT flags,
+ UINT *pcount,
+ DXGI_MODE_DESC *desc)
{
/* TODO: should we return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE when we don't
* support modesetting instead of fake modes?
*/
- pipe_format format = dxgi_to_pipe_format[EnumFormat];
+ pipe_format format = dxgi_to_pipe_format[enum_format];
if(parent->configs_by_pipe_format.count(format))
{
- if(!pDesc)
+ if(!desc)
{
- *pNumModes = num_modes;
+ *pcount = num_modes;
return S_OK;
}
- unsigned copy_modes = std::min(num_modes, *pNumModes);
+ unsigned copy_modes = std::min(num_modes, *pcount);
for(unsigned i = 0; i < copy_modes; ++i)
{
- pDesc[i] = dxgi_modes[i];
- pDesc[i].Format = EnumFormat;
+ desc[i] = dxgi_modes[i];
+ desc[i].Format = enum_format;
}
- *pNumModes = num_modes;
+ *pcount = num_modes;
if(copy_modes < num_modes)
return DXGI_ERROR_MORE_DATA;
}
else
{
- *pNumModes = 0;
+ *pcount = 0;
return S_OK;
}
}
virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode(
- __in const DXGI_MODE_DESC *pModeToMatch,
- __out DXGI_MODE_DESC *pClosestMatch,
- __in_opt IUnknown *pConcernedDevice)
+ const DXGI_MODE_DESC *pModeToMatch,
+ DXGI_MODE_DESC *closest_match,
+ IUnknown *concerned_device)
{
/* TODO: actually implement this */
DXGI_FORMAT dxgi_format = pModeToMatch->Format;
init_pipe_to_dxgi_format();
if(!parent->configs_by_pipe_format.count(format))
{
- if(!pConcernedDevice)
+ if(!concerned_device)
return E_FAIL;
else
{
}
}
- *pClosestMatch = dxgi_modes[0];
- pClosestMatch->Format = dxgi_format;
+ *closest_match = dxgi_modes[0];
+ closest_match->Format = dxgi_format;
return S_OK;
}
}
virtual HRESULT STDMETHODCALLTYPE TakeOwnership(
- __in IUnknown *pDevice,
- BOOL Exclusive)
+ IUnknown *device,
+ BOOL exclusive)
{
return S_OK;
}
}
virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities(
- __out DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps)
+ DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps)
{
- memset(pGammaCaps, 0, sizeof(*pGammaCaps));
+ memset(gamma_caps, 0, sizeof(*gamma_caps));
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE SetGammaControl(
- __in const DXGI_GAMMA_CONTROL *pArray)
+ const DXGI_GAMMA_CONTROL *pArray)
{
if(!gamma)
gamma = new DXGI_GAMMA_CONTROL;
}
virtual HRESULT STDMETHODCALLTYPE GetGammaControl(
- __out DXGI_GAMMA_CONTROL *pArray)
+ DXGI_GAMMA_CONTROL *pArray)
{
if(gamma)
*pArray = *gamma;
}
virtual HRESULT STDMETHODCALLTYPE SetDisplaySurface(
- __in IDXGISurface *pScanoutSurface)
+ IDXGISurface *scanout_surface)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData(
- __in IDXGISurface *pDestination)
+ IDXGISurface *destination)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
- __out DXGI_FRAME_STATISTICS *pStats)
+ DXGI_FRAME_STATISTICS *stats)
{
- memset(pStats, 0, sizeof(*pStats));
+ memset(stats, 0, sizeof(*stats));
#ifdef _WIN32
- QueryPerformanceCounter(&pStats->SyncQPCTime);
+ QueryPerformanceCounter(&stats->SyncQPCTime);
#endif
return E_NOTIMPL;
}
* surface and the contents become undefined.
* D3D may internally use multiple buffers, but you can't observe this, except
* by looking at the buffer contents after Present (but those are undefined).
- * If it uses multiple buffers internally, then it will normally use BufferCount buffers
+ * If it uses multiple buffers internally, then it will normally use buffer_count buffers
* (this has latency implications).
* Discard mode seems to internally use a single buffer in windowed mode,
- * even if DWM is enabled, and BufferCount buffers in fullscreen mode.
+ * even if DWM is enabled, and buffer_count buffers in fullscreen mode.
*
- * In sequential mode, the runtime alllocates BufferCount buffers.
+ * In sequential mode, the runtime alllocates buffer_count buffers.
* You can get each with GetBuffers(n).
* GetBuffers(0) ALWAYS points to the backbuffer to be presented and has the
* same usage constraints as the discard mode.
* GetBuffer(n) with n > 0 points to resources that are identical to buffer 0, but
* are classified as "read-only resources" (due to DXGI_USAGE_READ_ONLY),
* meaning that you can't create render target views on them, or use them as
- * a CopyResource/CopySubresourceRegion destination.
+ * a CopyResource/CopySubresourceRegion destination.
* It appears the only valid operation is to use them as a source for CopyResource
* and CopySubresourceRegion as well as just waiting for them to become
* buffer 0 again.
*
* There are three strategies:
* 1. Use a single buffer, and always copy it to a window system provided buffer, or
- * just give the buffer to the window system if it supports that
+ * just give the buffer to the window system if it supports that
* 2. Rotate the buffers in the D3D1x implementation, and recreate and rebind the views.
- * Don't support driver-provided command lists
+ * Don't support driver-provided command lists
* 3. Add this rotation functionality to the Gallium driver, with the idea that it would rotate
- * remap GPU virtual memory, so that virtual address are unchanged, but the physical
- * ones are rotated (so that pushbuffers remain valid).
- * If the driver does not support this, either fall back to (1), or have a layer doing this,
- * putting a deferred context layer over this intermediate layer.
+ * remap GPU virtual memory, so that virtual address are unchanged, but the physical
+ * ones are rotated (so that pushbuffers remain valid).
+ * If the driver does not support this, either fall back to (1), or have a layer doing this,
+ * putting a deferred context layer over this intermediate layer.
*
* (2) is not acceptable since it prevents an optimal implementation.
- * (3) is the ideal solution, but it is complicated.
+ * (3) is the ideal solution, but it is complicated.
*
* Hence, we implement (1) for now, and will switch to (3) later.
*
* I was unable to find any code using it either in DirectX SDK examples, or on the web.
*
* It seems the only reason you would use it is to not have to redraw from scratch, while
- * also possibly avoid a copy compared to BufferCount == 1, assuming that your
+ * also possibly avoid a copy compared to buffer_count == 1, assuming that your
* application is OK with having to redraw starting not from the last frame, but from
* one/two/more frames behind it.
*
- * A better design would forbid the user specifying BufferCount explicitly, and
+ * A better design would forbid the user specifying buffer_count explicitly, and
* would instead let the application give an upper bound on how old the buffer can
* become after presentation, with "infinite" being equivalent to discard.
* The runtime would then tell the application with frame number the buffer switched to
const unsigned semantic_indices[] = { 0, 0 };
vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, semantic_indices);
- vbuf.buffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, sizeof(quad_data));
+ vbuf.buffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM, sizeof(quad_data));
vbuf.buffer_offset = 0;
- vbuf.max_index = ~0;
vbuf.stride = 4 * sizeof(float);
pipe_buffer_write(pipe, vbuf.buffer, 0, sizeof(quad_data), quad_data);
if(desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL && desc.BufferCount != 1)
{
- std::cerr << "Gallium DXGI: if DXGI_SWAP_EFFECT_SEQUENTIAL is specified, only BufferCount == 1 is implemented, but " << desc.BufferCount << " was specified: ignoring this" << std::endl;
+ std::cerr << "Gallium DXGI: if DXGI_SWAP_EFFECT_SEQUENTIAL is specified, only buffer_count == 1 is implemented, but " << desc.BufferCount << " was specified: ignoring this" << std::endl;
// change the returned desc, so that the application might perhaps notice what we did and react well
desc.BufferCount = 1;
}
blitter.reset(new dxgi_blitter(pipe));
window = 0;
+
+ hr = resolve_zero_width_height(true);
+ if(!SUCCEEDED(hr))
+ throw hr;
}
void init_for_window()
{
XWindowAttributes xwa;
XGetWindowAttributes((Display*)parent->display, (Window)window, &xwa);
+ assert(adapter->configs_by_native_visual_id.count(xwa.visual->visualid));
config_num = adapter->configs_by_native_visual_id[xwa.visual->visualid];
}
else
pipe->destroy(pipe);
}
- virtual HRESULT STDMETHODCALLTYPE GetDevice(
- __in REFIID riid,
- __out void **ppDevice)
- {
- return dxgi_device->QueryInterface(riid, ppDevice);
- }
+ virtual HRESULT STDMETHODCALLTYPE GetDevice(
+ REFIID riid,
+ void **pdevice)
+ {
+ return dxgi_device->QueryInterface(riid, pdevice);
+ }
- HRESULT create_buffer0()
- {
- HRESULT hr;
+ HRESULT create_buffer0()
+ {
+ HRESULT hr;
ComPtr<IDXGISurface> new_buffer0;
DXGI_USAGE usage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT;
if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD)
templat.format = gallium_buffer0->format;
gallium_buffer0_view = pipe->create_sampler_view(pipe, gallium_buffer0, &templat);
return S_OK;
- }
+ }
bool validate()
{
return true;
}
- virtual HRESULT STDMETHODCALLTYPE Present(
- UINT SyncInterval,
- UINT Flags)
+ HRESULT resolve_zero_width_height(bool force = false)
{
- if(Flags & DXGI_PRESENT_TEST)
+ if(!force && desc.BufferDesc.Width && desc.BufferDesc.Height)
return S_OK;
+ unsigned width, height;
+ HRESULT hr = parent->backend->GetPresentSize(desc.OutputWindow, &width, &height);
+ if(!SUCCEEDED(hr))
+ return hr;
+
+ // On Windows, 8 is used, and a debug message saying so gets printed
+ if(!width)
+ width = 8;
+ if(!height)
+ height = 8;
+
+ if(!desc.BufferDesc.Width)
+ desc.BufferDesc.Width = width;
+ if(!desc.BufferDesc.Height)
+ desc.BufferDesc.Height = height;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Present(
+ UINT sync_interval,
+ UINT flags)
+ {
+ HRESULT hr;
+ if(flags & DXGI_PRESENT_TEST)
+ return parent->backend->TestPresent(desc.OutputWindow);
+
if(!buffer0)
{
HRESULT hr = create_buffer0();
struct pipe_resource* dst;
struct pipe_resource* src;
struct pipe_surface* dst_surface;
+ enum native_attachment att;
+
+ void* present_cookie;
+ hr = parent->backend->BeginPresent(desc.OutputWindow, &present_cookie, &cur_window, &rect, &rgndata, &preserve_aspect_ratio);
+ if(hr != S_OK)
+ return hr;
- void* present_cookie = parent->backend->BeginPresent(desc.OutputWindow, &cur_window, &rect, &rgndata, &preserve_aspect_ratio);
if(!cur_window || rect.left >= rect.right || rect.top >= rect.bottom)
goto end_present;
return DXGI_ERROR_DEVICE_REMOVED;
}
- db = !!(config->buffer_mask & NATIVE_ATTACHMENT_BACK_LEFT);
+ db = !!(config->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT));
dst = resources[db ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT];
src = gallium_buffer0;
dst_surface = 0;
+ assert(src);
+ assert(dst);
+
/* TODO: sharing the context for blitting won't work correctly if queries are active
* Hopefully no one is crazy enough to keep queries active while presenting, expecting
* sensible results.
unsigned blit_x, blit_y, blit_w, blit_h;
float black[4] = {0, 0, 0, 0};
- if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h)
- dst_surface = pipe->screen->get_tex_surface(pipe->screen, dst, 0, 0, 0, PIPE_BIND_RENDER_TARGET);
+ if(!formats_compatible || src->width0 != dst_w || src->height0 != dst_h) {
+ struct pipe_surface templat;
+ templat.usage = PIPE_BIND_RENDER_TARGET;
+ templat.format = dst->format;
+ templat.u.tex.level = 0;
+ templat.u.tex.first_layer = 0;
+ templat.u.tex.last_layer = 0;
+ dst_surface = pipe->create_surface(pipe, dst, &templat);
+ }
if(preserve_aspect_ratio)
{
if(formats_compatible && blit_w == src->width0 && blit_h == src->height0)
{
- pipe_subresource sr;
- sr.face = 0;
- sr.level = 0;
- pipe->resource_copy_region(pipe, dst, sr, rect.left, rect.top, 0, src, sr, 0, 0, 0, blit_w, blit_h);
+ pipe_box box;
+ box.x = box.y = box.z;
+ box.width = blit_w;
+ box.height = blit_h;
+ box.z = 1;
+ pipe->resource_copy_region(pipe, dst, 0, rect.left, rect.top, 0, src, 0, &box);
}
else
{
}
if(dst_surface)
- pipe->screen->tex_surface_destroy(dst_surface);
+ pipe->surface_destroy(pipe, dst_surface);
- if(db)
- {
- if(!surface->swap_buffers(surface))
- return DXGI_ERROR_DEVICE_REMOVED;
- }
- else
- {
- if(!surface->flush_frontbuffer(surface))
- return DXGI_ERROR_DEVICE_REMOVED;
- }
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, 0);
+
+ att = (db) ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT;
+ if(!surface->present(surface, att, FALSE, 0))
+ return DXGI_ERROR_DEVICE_REMOVED;
end_present:
parent->backend->EndPresent(desc.OutputWindow, present_cookie);
}
virtual HRESULT STDMETHODCALLTYPE GetBuffer(
- UINT Buffer,
- __in REFIID riid,
- __out void **ppSurface)
+ UINT Buffer,
+ REFIID riid,
+ void **ppSurface)
{
if(Buffer > 0)
{
/* TODO: implement somehow */
virtual HRESULT STDMETHODCALLTYPE SetFullscreenState(
- BOOL Fullscreen,
- __in_opt IDXGIOutput *pTarget)
+ BOOL fullscreen,
+ IDXGIOutput *target)
{
- fullscreen = Fullscreen;
- target = pTarget;
+ fullscreen = fullscreen;
+ target = target;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetFullscreenState(
- __out BOOL *pFullscreen,
- __out IDXGIOutput **ppTarget)
+ BOOL *out_fullscreen,
+ IDXGIOutput **out_target)
{
- if(pFullscreen)
- *pFullscreen = fullscreen;
- if(ppTarget)
- *ppTarget = target.ref();
+ if(out_fullscreen)
+ *out_fullscreen = fullscreen;
+ if(out_target)
+ *out_target = target.ref();
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetDesc(
- __out DXGI_SWAP_CHAIN_DESC *pDesc)
+ DXGI_SWAP_CHAIN_DESC *out_desc)
{
- *pDesc = desc;
+ *out_desc = desc;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE ResizeBuffers(
- UINT BufferCount,
- UINT Width,
- UINT Height,
- DXGI_FORMAT NewFormat,
- UINT SwapChainFlags)
+ UINT buffer_count,
+ UINT width,
+ UINT height,
+ DXGI_FORMAT new_format,
+ UINT swap_chain_flags)
{
if(buffer0)
{
}
if(desc.SwapEffect != DXGI_SWAP_EFFECT_SEQUENTIAL)
- desc.BufferCount = BufferCount;
- desc.BufferDesc.Format = NewFormat;
- desc.BufferDesc.Width = Width;
- desc.BufferDesc.Height = Height;
- desc.Flags = SwapChainFlags;
- return S_OK;
+ desc.BufferCount = buffer_count;
+ desc.BufferDesc.Format = new_format;
+ desc.BufferDesc.Width = width;
+ desc.BufferDesc.Height = height;
+ desc.Flags = swap_chain_flags;
+ return resolve_zero_width_height();
}
virtual HRESULT STDMETHODCALLTYPE ResizeTarget(
- const DXGI_MODE_DESC *pNewTargetParameters)
+ const DXGI_MODE_DESC *out_new_target_parameters)
{
/* TODO: implement */
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(
- __out IDXGIOutput **ppOutput)
+ IDXGIOutput **out_output)
{
- *ppOutput = adapter->outputs[0].ref();
+ *out_output = adapter->outputs[0].ref();
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
- __out DXGI_FRAME_STATISTICS *pStats)
+ DXGI_FRAME_STATISTICS *out_stats)
{
- memset(pStats, 0, sizeof(*pStats));
+ memset(out_stats, 0, sizeof(*out_stats));
#ifdef _WIN32
- QueryPerformanceCounter(&pStats->SyncQPCTime);
+ QueryPerformanceCounter(&out_stats->SyncQPCTime);
#endif
- pStats->PresentCount = present_count;
- pStats->PresentRefreshCount = present_count;
- pStats->SyncRefreshCount = present_count;
+ out_stats->PresentCount = present_count;
+ out_stats->PresentRefreshCount = present_count;
+ out_stats->SyncRefreshCount = present_count;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount(
- __out UINT *pLastPresentCount)
+ UINT *last_present_count)
{
- *pLastPresentCount = present_count;
+ *last_present_count = present_count;
return S_OK;
}
};
((GalliumDXGISwapChain*)swap_chain)->needs_validation = true;
}
-static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy, IDXGIAdapter1** pAdapter)
+static HRESULT GalliumDXGIAdapterCreate(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy, IDXGIAdapter1** out_adapter)
{
try
{
- *pAdapter = new GalliumDXGIAdapter(factory, platform, dpy);
+ *out_adapter = new GalliumDXGIAdapter(factory, platform, dpy);
return S_OK;
}
catch(HRESULT hr)
}
}
-static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** pOutput)
+static HRESULT GalliumDXGIOutputCreate(GalliumDXGIAdapter* adapter, const std::string& name, const struct native_connector* connector, IDXGIOutput** out_output)
{
try
{
- *pOutput = new GalliumDXGIOutput(adapter, name, connector);
+ *out_output = new GalliumDXGIOutput(adapter, name, connector);
return S_OK;
}
catch(HRESULT hr)
}
}
-static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** pSwapChain)
+static HRESULT GalliumDXGISwapChainCreate(GalliumDXGIFactory* factory, IUnknown* device, const DXGI_SWAP_CHAIN_DESC& desc, IDXGISwapChain** out_swap_chain)
{
try
{
- *pSwapChain = new GalliumDXGISwapChain(factory, device, desc);
+ *out_swap_chain = new GalliumDXGISwapChain(factory, device, desc);
return S_OK;
}
catch(HRESULT hr)
}
/* TODO: why did Microsoft add this? should we do something different for DXGI 1.0 and 1.1?
- * Or perhaps what they actually mean is "only create a single factory in your application"?
- * TODO: should we use a singleton here, so we never have multiple DXGI objects for the same thing? */
- HRESULT STDMETHODCALLTYPE CreateDXGIFactory1(
- __in REFIID riid,
- __out void **ppFactory
+ * Or perhaps what they actually mean is "only create a single factory in your application"?
+ * TODO: should we use a singleton here, so we never have multiple DXGI objects for the same thing? */
+ HRESULT STDMETHODCALLTYPE CreateDXGIFactory1(
+ REFIID riid,
+ void **out_factory
)
{
GalliumDXGIFactory* factory;
- *ppFactory = 0;
+ *out_factory = 0;
if(dxgi_thread_binding.platform)
factory = new GalliumDXGIFactory(dxgi_thread_binding.platform, dxgi_thread_binding.display, dxgi_thread_binding.backend);
else if(dxgi_default_binding.platform)
factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.backend);
else
factory = new GalliumDXGIFactory(native_get_x11_platform(), NULL, NULL);
- HRESULT hres = factory->QueryInterface(riid, ppFactory);
+ HRESULT hres = factory->QueryInterface(riid, out_factory);
factory->Release();
return hres;
}
- HRESULT STDMETHODCALLTYPE CreateDXGIFactory(
- __in REFIID riid,
- __out void **ppFactory
+ HRESULT STDMETHODCALLTYPE CreateDXGIFactory(
+ REFIID riid,
+ void **out_factor
)
{
- return CreateDXGIFactory1(riid, ppFactory);
+ return CreateDXGIFactory1(riid, out_factor);
}