HANDLE *pSharedHandle)
{
struct NineSurface9 *surface;
- struct pipe_screen *screen = This->screen;
- struct pipe_resource *resource = NULL;
HRESULT hr;
D3DSURFACE_DESC desc;
- struct pipe_resource templ;
DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u "
"Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n",
user_assert(Width && Height, D3DERR_INVALIDCALL);
user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL);
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.width0 = Width;
- templ.height0 = Height;
- templ.depth0 = 1;
- templ.array_size = 1;
- templ.last_level = 0;
- templ.nr_samples = (unsigned)MultiSample;
- templ.usage = PIPE_USAGE_DEFAULT;
- templ.flags = 0;
- templ.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
- switch (type) {
- case 0: templ.bind |= PIPE_BIND_RENDER_TARGET; break;
- case 1: templ.bind = d3d9_get_pipe_depth_format_bindings(Format); break;
- default:
- assert(type == 2);
- break;
- }
- templ.format = d3d9_to_pipe_format_checked(screen, Format, templ.target,
- templ.nr_samples, templ.bind,
- FALSE, Pool == D3DPOOL_SCRATCH);
-
- if (templ.format == PIPE_FORMAT_NONE && Format != D3DFMT_NULL)
- return D3DERR_INVALIDCALL;
-
desc.Format = Format;
desc.Type = D3DRTYPE_SURFACE;
desc.Usage = 0;
switch (type) {
case 0: desc.Usage = D3DUSAGE_RENDERTARGET; break;
case 1: desc.Usage = D3DUSAGE_DEPTHSTENCIL; break;
- default: break;
+ default: assert(type == 2); break;
}
- if (compressed_format(Format)) {
- const unsigned w = util_format_get_blockwidth(templ.format);
- const unsigned h = util_format_get_blockheight(templ.format);
+ hr = NineSurface9_new(This, NULL, NULL, NULL, 0, 0, 0, &desc, &surface);
+ if (SUCCEEDED(hr)) {
+ *ppSurface = (IDirect3DSurface9 *)surface;
- user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL);
+ if (surface->base.resource && Discard_or_Lockable && (type != 1))
+ surface->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
}
- if (Pool == D3DPOOL_DEFAULT && Format != D3DFMT_NULL) {
- /* resource_create doesn't return an error code, so check format here */
- user_assert(templ.format != PIPE_FORMAT_NONE, D3DERR_INVALIDCALL);
- resource = screen->resource_create(screen, &templ);
- user_assert(resource, D3DERR_OUTOFVIDEOMEMORY);
- if (Discard_or_Lockable && (desc.Usage & D3DUSAGE_RENDERTARGET))
- resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
- } else {
- resource = NULL;
- }
- hr = NineSurface9_new(This, NULL, resource, NULL, 0, 0, 0, &desc, &surface);
- pipe_resource_reference(&resource, NULL);
-
- if (SUCCEEDED(hr))
- *ppSurface = (IDirect3DSurface9 *)surface;
return hr;
}
union pipe_color_union rgba = {0};
struct pipe_surface *surf;
struct pipe_context *pipe = pParams->device->pipe;
+ bool allocate = !pContainer && pDesc->Format != D3DFMT_NULL;
DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n",
This, pParams->device, pResource, Level, Layer, pDesc);
/* Mark this as a special surface held by another internal resource. */
pParams->container = pContainer;
+ /* Make sure there's a Desc */
+ assert(pDesc);
+ /* D3DUSAGE_DYNAMIC isn't allowed on managed buffers */
user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) ||
(pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL);
- assert(pResource || (user_buffer && pDesc->Pool != D3DPOOL_DEFAULT) ||
- (!pContainer && pDesc->Pool != D3DPOOL_DEFAULT) ||
+ assert(allocate || pResource || user_buffer ||
pDesc->Format == D3DFMT_NULL);
-
+ assert(!allocate || (!pResource && !user_buffer));
assert(!pResource || !user_buffer);
assert(!user_buffer || pDesc->Pool != D3DPOOL_DEFAULT);
- /* The only way we can have !pContainer is being created
- * from create_zs_or_rt_surface with params 0 0 0 */
- assert(pContainer || (Level == 0 && Layer == 0 && TextureType == 0));
- /* Make sure no resource is passed for pool systemmem */
- assert(pDesc->Pool != D3DPOOL_SYSTEMMEM || !pResource);
+ assert(!pResource || pDesc->Pool == D3DPOOL_DEFAULT);
+ /* Allocation only from create_zs_or_rt_surface with params 0 0 0 */
+ assert(!allocate || (Level == 0 && Layer == 0 && TextureType == 0));
This->data = (uint8_t *)user_buffer;
+ /* TODO: this is (except width and height) duplicate from
+ * container info (in the pContainer case). Some refactoring is
+ * needed to avoid duplication */
This->base.info.screen = pParams->device->screen;
This->base.info.target = PIPE_TEXTURE_2D;
This->base.info.width0 = pDesc->Width;
This->base.info.array_size = 1;
This->base.info.nr_samples = pDesc->MultiSampleType;
This->base.info.usage = PIPE_USAGE_DEFAULT;
- This->base.info.bind = PIPE_BIND_SAMPLER_VIEW;
+ This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
+
+ if (pDesc->Usage & D3DUSAGE_RENDERTARGET) {
+ This->base.info.bind |= PIPE_BIND_RENDER_TARGET;
+ } else if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL) {
+ This->base.info.bind = d3d9_get_pipe_depth_format_bindings(pDesc->Format);
+ if (TextureType)
+ This->base.info.bind |= PIPE_BIND_SAMPLER_VIEW;
+ }
+
This->base.info.flags = 0;
This->base.info.format = d3d9_to_pipe_format_checked(This->base.info.screen,
pDesc->Format,
FALSE,
pDesc->Pool == D3DPOOL_SCRATCH);
- if (pDesc->Usage & D3DUSAGE_RENDERTARGET)
- This->base.info.bind |= PIPE_BIND_RENDER_TARGET;
- if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL)
- This->base.info.bind |= PIPE_BIND_DEPTH_STENCIL;
+ if (This->base.info.format == PIPE_FORMAT_NONE && pDesc->Format != D3DFMT_NULL)
+ return D3DERR_INVALIDCALL;
+
+ if (allocate && compressed_format(pDesc->Format)) {
+ const unsigned w = util_format_get_blockwidth(This->base.info.format);
+ const unsigned h = util_format_get_blockheight(This->base.info.format);
+
+ /* Note: In the !allocate case, the test could fail (lower levels of a texture) */
+ user_assert(!(pDesc->Width % w) && !(pDesc->Height % h), D3DERR_INVALIDCALL);
+ }
/* Get true format */
This->format_conversion = d3d9_to_pipe_format_checked(This->base.info.screen,
pDesc->Width);
}
- /* Ram buffer with no parent. Has to allocate the resource itself */
- if (!pResource && !pContainer) {
+ if ((allocate && pDesc->Pool != D3DPOOL_DEFAULT) || pDesc->Format == D3DFMT_NULL) {
+ /* Ram buffer with no parent. Has to allocate the resource itself */
assert(!user_buffer);
This->data = align_malloc(
nine_format_get_level_alloc_size(This->base.info.format,
return E_OUTOFMEMORY;
}
- if (pResource && (pDesc->Usage & D3DUSAGE_DYNAMIC))
- pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
+ hr = NineResource9_ctor(&This->base, pParams, pResource,
+ allocate && (pDesc->Pool == D3DPOOL_DEFAULT),
+ D3DRTYPE_SURFACE, pDesc->Pool, pDesc->Usage);
- hr = NineResource9_ctor(&This->base, pParams, pResource, FALSE, D3DRTYPE_SURFACE,
- pDesc->Pool, pDesc->Usage);
if (FAILED(hr))
return hr;
This->stride = nine_format_get_stride(This->base.info.format, pDesc->Width);
- if (pResource && NineSurface9_IsOffscreenPlain(This))
+ if (pDesc->Usage & D3DUSAGE_DYNAMIC)
pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
/* TODO: investigate what else exactly needs to be cleared */