예제 #1
0
static struct mp_image *alloc_pool(void *pctx, int fmt, int w, int h)
{
    struct vf_instance *vf = pctx;
    struct vf_priv_s *p = vf->priv;
    HRESULT hr;

    ID3D11Texture2D *texture = NULL;
    D3D11_TEXTURE2D_DESC texdesc = {
        .Width = w,
        .Height = h,
        .Format = p->out_format,
        .MipLevels = 1,
        .ArraySize = 1,
        .SampleDesc = { .Count = 1 },
        .Usage = D3D11_USAGE_DEFAULT,
        .BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
        .MiscFlags = p->out_shared ? D3D11_RESOURCE_MISC_SHARED : 0,
    };
    hr = ID3D11Device_CreateTexture2D(p->vo_dev, &texdesc, NULL, &texture);
    if (FAILED(hr))
        return NULL;

    struct mp_image *mpi = mp_image_new_custom_ref(NULL, texture, release_tex);
    if (!mpi)
        abort();

    mp_image_setfmt(mpi, p->out_params.imgfmt);
    mp_image_set_size(mpi, w, h);
    mpi->params.hw_subfmt = p->out_params.hw_subfmt;

    mpi->planes[1] = (void *)texture;
    mpi->planes[2] = (void *)(intptr_t)0;

    return mpi;
}
예제 #2
0
static inline bool gl_shtex_init_d3d11_tex(void)
{
	IDXGIResource *dxgi_res;
	HRESULT hr;

	D3D11_TEXTURE2D_DESC desc      = {0};
	desc.Width                     = data.cx;
	desc.Height                    = data.cy;
	desc.MipLevels                 = 1;
	desc.ArraySize                 = 1;
	desc.Format                    = DXGI_FORMAT_B8G8R8A8_UNORM;
	desc.SampleDesc.Count          = 1;
	desc.Usage                     = D3D11_USAGE_DEFAULT;
	desc.MiscFlags                 = D3D11_RESOURCE_MISC_SHARED;
	desc.BindFlags                 = D3D11_BIND_RENDER_TARGET |
	                                 D3D11_BIND_SHADER_RESOURCE;

	hr = ID3D11Device_CreateTexture2D(data.d3d11_device, &desc, NULL,
			&data.d3d11_tex);
	if (FAILED(hr)) {
		hlog_hr("gl_shtex_init_d3d11_tex: failed to create texture",
				hr);
		return false;
	}

	hr = ID3D11Device_QueryInterface(data.d3d11_tex,
			&GUID_IDXGIResource, (void**)&dxgi_res);
	if (FAILED(hr)) {
		hlog_hr("gl_shtex_init_d3d11_tex: failed to get IDXGIResource",
				hr);
		return false;
	}

	hr = IDXGIResource_GetSharedHandle(dxgi_res, &data.handle);
	IDXGIResource_Release(dxgi_res);

	if (FAILED(hr)) {
		hlog_hr("gl_shtex_init_d3d11_tex: failed to get shared handle",
				hr);
		return false;
	}

	return true;
}
예제 #3
0
파일: d3d11va.c 프로젝트: DZW314/mpv
static int d3d11va_init_decoder(struct lavc_ctx *s, int w, int h)
{
    HRESULT hr;
    int ret = -1;
    struct priv *p = s->hwdec_priv;
    TA_FREEP(&p->decoder);

    ID3D11Texture2D *texture = NULL;
    void *tmp = talloc_new(NULL);

    UINT n_guids = ID3D11VideoDevice_GetVideoDecoderProfileCount(p->video_dev);
    GUID *device_guids = talloc_array(tmp, GUID, n_guids);
    for (UINT i = 0; i < n_guids; i++) {
        GUID *guid = &device_guids[i];
        hr = ID3D11VideoDevice_GetVideoDecoderProfile(p->video_dev, i, guid);
        if (FAILED(hr)) {
            MP_ERR(p, "Failed to get VideoDecoderProfile %d: %s\n",
                   i, mp_HRESULT_to_str(hr));
            goto done;
        }
        dump_decoder_info(s, guid);
    }

    struct d3d_decoder_fmt fmt =
        d3d_select_decoder_mode(s, device_guids, n_guids,
                                d3d11_formats, MP_ARRAY_SIZE(d3d11_formats),
                                d3d11_format_supported);
    if (!fmt.format) {
        MP_ERR(p, "Failed to find a suitable decoder\n");
        goto done;
    }

    struct d3d11va_decoder *decoder = talloc_zero(tmp, struct d3d11va_decoder);
    talloc_set_destructor(decoder, d3d11va_destroy_decoder);
    decoder->mpfmt_decoded = fmt.format->mpfmt;

    int n_surfaces = hwdec_get_max_refs(s) + ADDITIONAL_SURFACES;
    int w_align = w, h_align = h;
    d3d_surface_align(s, &w_align, &h_align);

    D3D11_TEXTURE2D_DESC tex_desc = {
        .Width            = w_align,
        .Height           = h_align,
        .MipLevels        = 1,
        .Format           = fmt.format->dxfmt,
        .SampleDesc.Count = 1,
        .MiscFlags        = 0,
        .ArraySize        = n_surfaces,
        .Usage            = D3D11_USAGE_DEFAULT,
        .BindFlags        = D3D11_BIND_DECODER | D3D11_BIND_SHADER_RESOURCE,
        .CPUAccessFlags   = 0,
    };
    hr = ID3D11Device_CreateTexture2D(p->device, &tex_desc, NULL, &texture);
    if (FAILED(hr)) {
        MP_ERR(p, "Failed to create Direct3D11 texture with %d surfaces: %s\n",
               n_surfaces, mp_HRESULT_to_str(hr));
        goto done;
    }

    if (s->hwdec->type == HWDEC_D3D11VA_COPY) {
        // create staging texture shared with the CPU with mostly the same
        // parameters as the above decoder-bound texture
        ID3D11Texture2D_GetDesc(texture, &tex_desc);
        tex_desc.MipLevels      = 1;
        tex_desc.MiscFlags      = 0;
        tex_desc.ArraySize      = 1;
        tex_desc.Usage          = D3D11_USAGE_STAGING;
        tex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
        tex_desc.BindFlags      = 0;
        hr = ID3D11Device_CreateTexture2D(p->device, &tex_desc, NULL,
                                          &decoder->staging);
        if (FAILED(hr)) {
            MP_ERR(p, "Failed to create staging texture: %s\n",
                   mp_HRESULT_to_str(hr));
            goto done;
        }
    }

    // pool to hold the mp_image wrapped surfaces
    decoder->pool = talloc_steal(decoder, mp_image_pool_new(n_surfaces));
    // array of the same surfaces (needed by ffmpeg)
    ID3D11VideoDecoderOutputView **surfaces =
        talloc_array_ptrtype(decoder->pool, surfaces, n_surfaces);

    D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC view_desc = {
        .DecodeProfile = *fmt.guid,
        .ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D,
    };
    for (int i = 0; i < n_surfaces; i++) {
        ID3D11VideoDecoderOutputView **surface = &surfaces[i];
        view_desc.Texture2D.ArraySlice = i;
        hr = ID3D11VideoDevice_CreateVideoDecoderOutputView(
            p->video_dev, (ID3D11Resource *)texture, &view_desc, surface);
        if (FAILED(hr)) {
            MP_ERR(p, "Failed getting decoder output view %d: %s\n",
                   i, mp_HRESULT_to_str(hr));
            goto done;
        }
        struct mp_image *img = d3d11va_new_ref(*surface, w, h);
        ID3D11VideoDecoderOutputView_Release(*surface); // transferred to img
        if (!img) {
            MP_ERR(p, "Failed to create D3D11VA image %d\n", i);
            goto done;
        }
        mp_image_pool_add(decoder->pool, img); // transferred to pool
    }

    D3D11_VIDEO_DECODER_DESC decoder_desc = {
        .Guid         = *fmt.guid,
        .SampleWidth  = w,
        .SampleHeight = h,
        .OutputFormat = fmt.format->dxfmt,
    };
    UINT n_cfg;
    hr = ID3D11VideoDevice_GetVideoDecoderConfigCount(p->video_dev,
                                                      &decoder_desc, &n_cfg);
    if (FAILED(hr)) {
        MP_ERR(p, "Failed to get number of decoder configurations: %s)",
               mp_HRESULT_to_str(hr));
        goto done;
    }

    // pick the config with the highest score
    D3D11_VIDEO_DECODER_CONFIG *decoder_config =
        talloc_zero(decoder, D3D11_VIDEO_DECODER_CONFIG);
    unsigned max_score = 0;
    for (UINT i = 0; i < n_cfg; i++) {
        D3D11_VIDEO_DECODER_CONFIG cfg;
        hr = ID3D11VideoDevice_GetVideoDecoderConfig(p->video_dev,
                                                     &decoder_desc,
                                                     i, &cfg);
        if (FAILED(hr)) {
            MP_ERR(p, "Failed to get decoder config %d: %s\n",
                   i, mp_HRESULT_to_str(hr));
            goto done;
        }
        unsigned score = d3d_decoder_config_score(
            s, &cfg.guidConfigBitstreamEncryption, cfg.ConfigBitstreamRaw);
        if (score > max_score) {
            max_score       = score;
            *decoder_config = cfg;
        }
    }
    if (!max_score) {
        MP_ERR(p, "Failed to find a suitable decoder configuration\n");
        goto done;
    }

    hr = ID3D11VideoDevice_CreateVideoDecoder(p->video_dev, &decoder_desc,
                                              decoder_config,
                                              &decoder->decoder);
    if (FAILED(hr)) {
        MP_ERR(p, "Failed to create video decoder: %s\n",
               mp_HRESULT_to_str(hr));
        goto done;
    }

    struct AVD3D11VAContext *avd3d11va_ctx = s->avctx->hwaccel_context;
    avd3d11va_ctx->decoder       = decoder->decoder;
    avd3d11va_ctx->video_context = p->video_ctx;
    avd3d11va_ctx->cfg           = decoder_config;
    avd3d11va_ctx->surface_count = n_surfaces;
    avd3d11va_ctx->surface       = surfaces;
    avd3d11va_ctx->workaround    = is_clearvideo(fmt.guid) ?
                                   FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO : 0;

    p->decoder = talloc_steal(NULL, decoder);
    ret = 0;
done:
    // still referenced by pool images / surfaces
    if (texture)
        ID3D11Texture2D_Release(texture);

    talloc_free(tmp);
    return ret;
}

static void destroy_device(struct lavc_ctx *s)
{
    struct priv *p = s->hwdec_priv;

    if (p->device)
        ID3D11Device_Release(p->device);

    if (p->device_ctx)
        ID3D11DeviceContext_Release(p->device_ctx);
}

static bool create_device(struct lavc_ctx *s, BOOL thread_safe)
{
    HRESULT hr;
    struct priv *p = s->hwdec_priv;

    d3d_load_dlls();
    if (!d3d11_dll) {
        MP_ERR(p, "Failed to load D3D11 library\n");
        return false;
    }

    PFN_D3D11_CREATE_DEVICE CreateDevice =
        (void *)GetProcAddress(d3d11_dll, "D3D11CreateDevice");
    if (!CreateDevice) {
        MP_ERR(p, "Failed to get D3D11CreateDevice symbol from DLL: %s\n",
               mp_LastError_to_str());
        return false;
    }

    hr = CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
                      D3D11_CREATE_DEVICE_VIDEO_SUPPORT, NULL, 0,
                      D3D11_SDK_VERSION, &p->device, NULL, &p->device_ctx);
    if (FAILED(hr)) {
        MP_ERR(p, "Failed to create D3D11 Device: %s\n",
               mp_HRESULT_to_str(hr));
        return false;
    }

    ID3D10Multithread *multithread;
    hr = ID3D11Device_QueryInterface(p->device, &IID_ID3D10Multithread,
                                     (void **)&multithread);
    if (FAILED(hr)) {
        MP_ERR(p, "Failed to get Multithread interface: %s\n",
               mp_HRESULT_to_str(hr));
        return false;
    }
    ID3D10Multithread_SetMultithreadProtected(multithread, thread_safe);
    ID3D10Multithread_Release(multithread);
    return true;
}

static void d3d11va_uninit(struct lavc_ctx *s)
{
    struct priv *p = s->hwdec_priv;
    if (!p)
        return;

    talloc_free(p->decoder);
    av_freep(&s->avctx->hwaccel_context);

    if (p->video_dev)
        ID3D11VideoDevice_Release(p->video_dev);

    if (p->video_ctx)
        ID3D11VideoContext_Release(p->video_ctx);

    destroy_device(s);

    TA_FREEP(&s->hwdec_priv);
}

static int d3d11va_init(struct lavc_ctx *s)
{
    HRESULT hr;
    struct priv *p = talloc_zero(NULL, struct priv);
    if (!p)
        return -1;

    s->hwdec_priv = p;
    p->log = mp_log_new(s, s->log, "d3d11va");
    if (s->hwdec->type == HWDEC_D3D11VA_COPY) {
        mp_check_gpu_memcpy(p->log, NULL);
        p->sw_pool = talloc_steal(p, mp_image_pool_new(17));
    }

    p->device = hwdec_devices_load(s->hwdec_devs, s->hwdec->type);
    if (p->device) {
        ID3D11Device_AddRef(p->device);
        ID3D11Device_GetImmediateContext(p->device, &p->device_ctx);
        if (!p->device_ctx)
            goto fail;
        MP_VERBOSE(p, "Using VO-supplied device %p.\n", p->device);
    } else if (s->hwdec->type == HWDEC_D3D11VA) {
        MP_ERR(p, "No Direct3D device provided for native d3d11 decoding\n");
        goto fail;
    } else {
        if (!create_device(s, FALSE))
            goto fail;
    }

    hr = ID3D11DeviceContext_QueryInterface(p->device_ctx,
                                            &IID_ID3D11VideoContext,
                                            (void **)&p->video_ctx);
    if (FAILED(hr)) {
        MP_ERR(p, "Failed to get VideoContext interface: %s\n",
               mp_HRESULT_to_str(hr));
        goto fail;
    }

    hr = ID3D11Device_QueryInterface(p->device,
                                     &IID_ID3D11VideoDevice,
                                     (void **)&p->video_dev);
    if (FAILED(hr)) {
        MP_ERR(p, "Failed to get VideoDevice interface. %s\n",
               mp_HRESULT_to_str(hr));
        goto fail;
    }

    s->avctx->hwaccel_context = av_d3d11va_alloc_context();
    if (!s->avctx->hwaccel_context) {
        MP_ERR(p, "Failed to allocate hwaccel_context\n");
        goto fail;
    }

    return 0;
fail:
    d3d11va_uninit(s);
    return -1;
}

static int d3d11va_probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec,
                         const char *codec)
{
    // d3d11va-copy can do without external context; dxva2 requires it.
    if (hwdec->type != HWDEC_D3D11VA_COPY) {
        if (!hwdec_devices_load(ctx->hwdec_devs, HWDEC_D3D11VA))
            return HWDEC_ERR_NO_CTX;
    }
    return d3d_probe_codec(codec);
}

const struct vd_lavc_hwdec mp_vd_lavc_d3d11va = {
    .type           = HWDEC_D3D11VA,
    .image_format   = IMGFMT_D3D11VA,
    .probe          = d3d11va_probe,
    .init           = d3d11va_init,
    .uninit         = d3d11va_uninit,
    .init_decoder   = d3d11va_init_decoder,
    .allocate_image = d3d11va_allocate_image,
    .process_image  = d3d11va_update_image_attribs,
};

const struct vd_lavc_hwdec mp_vd_lavc_d3d11va_copy = {
    .type           = HWDEC_D3D11VA_COPY,
    .copying        = true,
    .image_format   = IMGFMT_D3D11VA,
    .probe          = d3d11va_probe,
    .init           = d3d11va_init,
    .uninit         = d3d11va_uninit,
    .init_decoder   = d3d11va_init_decoder,
    .allocate_image = d3d11va_allocate_image,
    .process_image  = d3d11va_retrieve_image,
    .delay_queue    = HWDEC_DELAY_QUEUE_COUNT,
};
예제 #4
0
/**
 * It creates a Direct3D11 decoder using the given video format
 */
static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_format_t *fmt, bool b_threading)
{
    vlc_va_sys_t *sys = va->sys;
    directx_sys_t *dx_sys = &va->sys->dx_sys;
    HRESULT hr;

    ID3D10Multithread *pMultithread;
    hr = ID3D11Device_QueryInterface( (ID3D11Device*) dx_sys->d3ddev, &IID_ID3D10Multithread, (void **)&pMultithread);
    if (SUCCEEDED(hr)) {
        ID3D10Multithread_SetMultithreadProtected(pMultithread, b_threading && dx_sys->thread_count > 1);
        ID3D10Multithread_Release(pMultithread);
    }

    D3D11_TEXTURE2D_DESC texDesc;
    ZeroMemory(&texDesc, sizeof(texDesc));
    texDesc.Width = dx_sys->surface_width;
    texDesc.Height = dx_sys->surface_height;
    texDesc.MipLevels = 1;
    texDesc.Format = sys->render;
    texDesc.SampleDesc.Count = 1;
    texDesc.MiscFlags = 0;
    texDesc.ArraySize = dx_sys->surface_count;
    texDesc.Usage = D3D11_USAGE_DEFAULT;
    texDesc.BindFlags = D3D11_BIND_DECODER;
    texDesc.CPUAccessFlags = 0;

    ID3D11Texture2D *p_texture;
    hr = ID3D11Device_CreateTexture2D( (ID3D11Device*) dx_sys->d3ddev, &texDesc, NULL, &p_texture );
    if (FAILED(hr)) {
        msg_Err(va, "CreateTexture2D %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
        return VLC_EGENERIC;
    }

    D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
    ZeroMemory(&viewDesc, sizeof(viewDesc));
    viewDesc.DecodeProfile = dx_sys->input;
    viewDesc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;

    int surface_count = dx_sys->surface_count;
    for (dx_sys->surface_count = 0; dx_sys->surface_count < surface_count; dx_sys->surface_count++) {
        viewDesc.Texture2D.ArraySlice = dx_sys->surface_count;

        hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( (ID3D11VideoDevice*) dx_sys->d3ddec,
                                                             (ID3D11Resource*) p_texture,
                                                             &viewDesc,
                                                             (ID3D11VideoDecoderOutputView**) &dx_sys->hw_surface[dx_sys->surface_count] );
        if (FAILED(hr)) {
            msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
            ID3D11Texture2D_Release(p_texture);
            return VLC_EGENERIC;
        }
    }
    msg_Dbg(va, "ID3D11VideoDecoderOutputView succeed with %d surfaces (%dx%d)",
            dx_sys->surface_count, dx_sys->surface_width, dx_sys->surface_height);

    D3D11_VIDEO_DECODER_DESC decoderDesc;
    ZeroMemory(&decoderDesc, sizeof(decoderDesc));
    decoderDesc.Guid = dx_sys->input;
    decoderDesc.SampleWidth = fmt->i_width;
    decoderDesc.SampleHeight = fmt->i_height;
    decoderDesc.OutputFormat = sys->render;

    UINT cfg_count;
    hr = ID3D11VideoDevice_GetVideoDecoderConfigCount( (ID3D11VideoDevice*) dx_sys->d3ddec, &decoderDesc, &cfg_count );
    if (FAILED(hr)) {
        msg_Err(va, "GetVideoDecoderConfigCount failed. (hr=0x%lX)", hr);
        return VLC_EGENERIC;
    }

    /* List all configurations available for the decoder */
    D3D11_VIDEO_DECODER_CONFIG cfg_list[cfg_count];
    for (unsigned i = 0; i < cfg_count; i++) {
        hr = ID3D11VideoDevice_GetVideoDecoderConfig( (ID3D11VideoDevice*) dx_sys->d3ddec, &decoderDesc, i, &cfg_list[i] );
        if (FAILED(hr)) {
            msg_Err(va, "GetVideoDecoderConfig failed. (hr=0x%lX)", hr);
            return VLC_EGENERIC;
        }
    }

    msg_Dbg(va, "we got %d decoder configurations", cfg_count);

    /* Select the best decoder configuration */
    int cfg_score = 0;
    for (unsigned i = 0; i < cfg_count; i++) {
        const D3D11_VIDEO_DECODER_CONFIG *cfg = &cfg_list[i];

        /* */
        msg_Dbg(va, "configuration[%d] ConfigBitstreamRaw %d",
                i, cfg->ConfigBitstreamRaw);

        /* */
        int score;
        if (cfg->ConfigBitstreamRaw == 1)
            score = 1;
        else if (codec_id == AV_CODEC_ID_H264 && cfg->ConfigBitstreamRaw == 2)
            score = 2;
        else
            continue;
        if (IsEqualGUID(&cfg->guidConfigBitstreamEncryption, &DXVA_NoEncrypt))
            score += 16;

        if (cfg_score < score) {
            sys->cfg = *cfg;
            cfg_score = score;
        }
    }
    if (cfg_score <= 0) {
        msg_Err(va, "Failed to find a supported decoder configuration");
        return VLC_EGENERIC;
    }

    /* Create the decoder */
    ID3D11VideoDecoder *decoder;
    hr = ID3D11VideoDevice_CreateVideoDecoder( (ID3D11VideoDevice*) dx_sys->d3ddec, &decoderDesc, &sys->cfg, &decoder );
    if (FAILED(hr)) {
        msg_Err(va, "ID3D11VideoDevice_CreateVideoDecoder failed. (hr=0x%lX)", hr);
        dx_sys->decoder = NULL;
        return VLC_EGENERIC;
    }
    dx_sys->decoder = (IUnknown*) decoder;

    msg_Dbg(va, "DxCreateDecoderSurfaces succeed");
    return VLC_SUCCESS;
}
예제 #5
0
qboolean D3D11_BeginShadowMap(int id, int w, int h)
{
	D3D11_TEXTURE2D_DESC texdesc;
	HRESULT hr;

	if (!shadowmap_dsview[id] && !shadowmap_rtview[id])
	{
		memset(&texdesc, 0, sizeof(texdesc));

		texdesc.Width = w;
		texdesc.Height = h;
		texdesc.MipLevels = 1;
		texdesc.ArraySize = 1;
		texdesc.Format = shadowfmts[shadowfmt][1];
		texdesc.SampleDesc.Count = 1;
		texdesc.SampleDesc.Quality = 0;
		texdesc.Usage = D3D11_USAGE_DEFAULT;
		texdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
		texdesc.CPUAccessFlags = 0;
		texdesc.MiscFlags = 0;

		if (shadowfmt == 2)
			texdesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;

		// Create the texture
		if (!shadowmap_texture[id].ptr)
		{
			hr = ID3D11Device_CreateTexture2D(pD3DDev11, &texdesc, NULL, (ID3D11Texture2D **)&shadowmap_texture[id].ptr);
			if (FAILED(hr))
				return false;
		}


		if (shadowfmt == 2)
		{
			hr = ID3D11Device_CreateRenderTargetView(pD3DDev11, (ID3D11Resource *)shadowmap_texture[id].ptr, NULL, &shadowmap_rtview[id]);
		}
		else
		{
			D3D11_DEPTH_STENCIL_VIEW_DESC rtdesc;
			rtdesc.Format = shadowfmts[shadowfmt][2];
			rtdesc.Flags = 0;
			rtdesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
			rtdesc.Texture2D.MipSlice = 0;
			hr = ID3D11Device_CreateDepthStencilView(pD3DDev11, (ID3D11Resource *)shadowmap_texture[id].ptr, &rtdesc, &shadowmap_dsview[id]);
		}
		if (FAILED(hr))
			return false;
	}
	D3D11BE_UnbindAllTextures();
	if (shadowfmt == 2)
	{
		float colours[4] = {0, 1, 0, 0};
		colours[0] = frandom();
		colours[1] = frandom();
		colours[2] = frandom();
		ID3D11DeviceContext_OMSetRenderTargets(d3ddevctx, 1, &shadowmap_rtview[id], shadowmap_dsview[id]);
		ID3D11DeviceContext_ClearRenderTargetView(d3ddevctx, shadowmap_rtview[id], colours);
	}
	else
	{
		ID3D11DeviceContext_OMSetRenderTargets(d3ddevctx, 0, NULL, shadowmap_dsview[id]);
		ID3D11DeviceContext_ClearDepthStencilView(d3ddevctx, shadowmap_dsview[id], D3D11_CLEAR_DEPTH, 1.0f, 0);
	}
	return true;
}
예제 #6
0
qboolean D3D11_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips)
{
	int bytesperpixel = 4;
	int bcbytes = 0;
	HRESULT hr;
	D3D11_TEXTURE2D_DESC tdesc = {0};
	D3D11_SUBRESOURCE_DATA subresdesc[sizeof(mips->mip) / sizeof(mips->mip[0])];
	int i;

	if (!sh_config.texfmt[mips->encoding])
	{
		Con_Printf("Texture encoding %i not supported by d3d11\n", mips->encoding);
		return false;
	}

	tdesc.Width = mips->mip[0].width;
	tdesc.Height = mips->mip[0].height;
	tdesc.ArraySize = 1;
	tdesc.SampleDesc.Count = 1;
	tdesc.SampleDesc.Quality = 0;
	tdesc.Usage = mips->mip[0].data?D3D11_USAGE_IMMUTABLE:D3D11_USAGE_DYNAMIC;
	tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	tdesc.CPUAccessFlags = (mips->mip[0].data)?0:D3D11_CPU_ACCESS_WRITE;
	tdesc.MiscFlags = 0;

	if (tex->flags & IF_RENDERTARGET)
	{
		tdesc.BindFlags |= D3D11_BIND_RENDER_TARGET;
		tdesc.Usage = D3D11_USAGE_DEFAULT;
		tdesc.CPUAccessFlags = 0;
	}

	if (mips->type == PTI_CUBEMAP)
	{
		tdesc.ArraySize *= 6;
		tdesc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
	}
	else if (mips->type == PTI_3D)
		return false;	//nyi

//d3d11.1 formats
#define DXGI_FORMAT_B4G4R4A4_UNORM 115

	switch(mips->encoding)
	{
	default:
		return false;
	case PTI_DEPTH16:
		tdesc.Format = DXGI_FORMAT_D16_UNORM;
		tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
		bytesperpixel = 2;
		break;
	case PTI_DEPTH24:
		tdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
		tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
		bytesperpixel = 3;
		break;
	case PTI_DEPTH32:
		tdesc.Format = DXGI_FORMAT_D32_FLOAT;
		tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
		bytesperpixel = 4;
		break;
	case PTI_DEPTH24_8:
		tdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
		tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
		bytesperpixel = 4;
		break;
	case PTI_RGB565:
		tdesc.Format = DXGI_FORMAT_B5G6R5_UNORM;
		bytesperpixel = 2;
		break;
//	case PTI_RGBA5551:
//		tdesc.Format = DXGI_FORMAT_A1B5G5R5_UNORM;
//		bytesperpixel = 2;
//		break;
	case PTI_ARGB1555:
		tdesc.Format = DXGI_FORMAT_B5G5R5A1_UNORM;
		bytesperpixel = 2;
		break;
	case PTI_RGBA4444:
		tdesc.Format = DXGI_FORMAT_B4G4R4A4_UNORM;
		bytesperpixel = 2;
		break;
//	case PTI_ARGB4444:
//		tdesc.Format = DXGI_FORMAT_A4B4G4R4_UNORM;
//		bytesperpixel = 2;
//		break;
	case PTI_RGBA8:
		tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		bytesperpixel = 4;
		break;
	case PTI_RGBX8:	//d3d11 has no alphaless format. be sure to proprly disable alpha in the shader. 
		tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		bytesperpixel = 4;
		break;
	case PTI_BGRA8:
		tdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
		bytesperpixel = 4;
		break;
	case PTI_BGRX8:
		tdesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
		bytesperpixel = 4;
		break;

	case PTI_S3RGB1:	//d3d11 provides no way to disable alpha with dxt1. be sure to proprly disable alpha in the shader. 
	case PTI_S3RGBA1:
		tdesc.Format = DXGI_FORMAT_BC1_UNORM;
		bcbytes = 8;
		break;
	case PTI_S3RGBA3:
		tdesc.Format = DXGI_FORMAT_BC2_UNORM;
		bcbytes = 16;
		break;
	case PTI_S3RGBA5:
		tdesc.Format = DXGI_FORMAT_BC3_UNORM;
		bcbytes = 16;
		break;
	}

	if (!mips->mip[0].data)
	{
		subresdesc[0].pSysMem = NULL;
		//one mip, but no data. happens with rendertargets
		tdesc.MipLevels = 1;
	}
	else
	{
		for (i = 0; i < mips->mipcount; i++)
		{
			subresdesc[i].pSysMem = mips->mip[i].data;
			if (bcbytes)
			{
				subresdesc[i].SysMemPitch = ((mips->mip[i].width+3)/4) * bcbytes;
				subresdesc[i].SysMemSlicePitch = mips->mip[i].datasize;
			}
			else
			{
				subresdesc[i].SysMemPitch = mips->mip[i].width*bytesperpixel;
				subresdesc[i].SysMemSlicePitch = mips->mip[i].datasize;//mips->mip[i].width*mips->mip[i].height*bytesperpixel;
			}
		}
		tdesc.MipLevels = i/tdesc.ArraySize;
	}

	D3D11_DestroyTexture(tex);
	hr = ID3D11Device_CreateTexture2D(pD3DDev11, &tdesc, (mips->mip[0].data?subresdesc:NULL), (ID3D11Texture2D**)&tex->ptr);

	return !FAILED(hr);
}
예제 #7
0
파일: d3d11_wm.c 프로젝트: AgentD/sgui
sgui_ctx_wm* d3d11_wm_create( sgui_window* wnd )
{
    D3D11_SHADER_RESOURCE_VIEW_DESC rvdesc;
    D3D11_SAMPLER_DESC sampdesc;
    D3D11_SUBRESOURCE_DATA data;
    unsigned int width, height;
    D3D11_TEXTURE2D_DESC desc;
    sgui_d3d11_context* ctx;
    sgui_subwm_skin* skin;
    sgui_d3d11_wm* this;
    sgui_ctx_wm* super;
    HRESULT status;

    ctx = (sgui_d3d11_context*)sgui_window_get_context( wnd );

    if( !ctx )
        return NULL;

    this = calloc( 1, sizeof(sgui_d3d11_wm) );
    super = (sgui_ctx_wm*)this;

    if( !this )
        return NULL;

    memset( &desc,     0, sizeof(desc)     );
    memset( &data,     0, sizeof(data)     );
    memset( &rvdesc,   0, sizeof(rvdesc)   );
    memset( &sampdesc, 0, sizeof(sampdesc) );

    skin = sgui_subwm_skin_get( );
    skin->get_ctx_skin_texture_size( skin, &width, &height );

    desc.Width                 = width;
    desc.Height                = height;
    desc.MipLevels             = 1;
    desc.ArraySize             = 1;
    desc.SampleDesc.Count      = 1;
    desc.Format                = DXGI_FORMAT_R8G8B8A8_UNORM;
    desc.Usage                 = D3D11_USAGE_IMMUTABLE;
    desc.BindFlags             = D3D11_BIND_SHADER_RESOURCE;

    data.pSysMem               = skin->get_ctx_skin_texture( skin );
    data.SysMemPitch           = width*4;

    rvdesc.Format              = DXGI_FORMAT_R8G8B8A8_UNORM;
    rvdesc.ViewDimension       = D3D11_SRV_DIMENSION_TEXTURE2D;
    rvdesc.Texture2D.MipLevels = 1;

    sampdesc.Filter            = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
    sampdesc.ComparisonFunc    = D3D11_COMPARISON_NEVER;
    sampdesc.AddressU          = D3D11_TEXTURE_ADDRESS_WRAP;
    sampdesc.AddressV          = D3D11_TEXTURE_ADDRESS_WRAP;
    sampdesc.AddressW          = D3D11_TEXTURE_ADDRESS_WRAP;

    status = ID3D11Device_CreateTexture2D( ctx->dev, &desc, &data,
                                           &this->skintex );

    if( status!=S_OK || !this->skintex )
        goto fail;

    status = ID3D11Device_CreateShaderResourceView( ctx->dev,
                                                    (void*)this->skintex,
                                                    &rvdesc, &this->view );

    if( status!=S_OK || !this->view )
        goto failtex;

    status = ID3D11Device_CreateSamplerState( ctx->dev, &sampdesc,
                                              &this->sampler );

    if( status!=S_OK || !this->sampler )
        goto failview;

    /* init */
    super->wnd      = wnd;
    super->draw_gui = d3d11_wm_draw_gui;
    super->destroy  = d3d11_wm_destroy;
    return super;
failview:
    ID3D11ShaderResourceView_Release( this->view );
failtex:
    ID3D11Texture2D_Release( this->skintex );
fail:
    free( this );
    return NULL;
}