Result GraphicsInterfaceD3D11::createTexture2D(void **dst_tex, int width, int height, TextureFormat format, const void *data, ResourceFlags flags) { size_t texel_size = GetTexelSize(format); DXGI_FORMAT internal_format = GetDXGIFormat(format); D3D11_TEXTURE2D_DESC desc = { (UINT)width, (UINT)height, 1, 1, internal_format, { 1, 0 }, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0 }; if (flags & ResourceFlags::CPU_Write) { desc.Usage = D3D11_USAGE_DYNAMIC; desc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; } if (flags & ResourceFlags::CPU_Read) { desc.Usage = D3D11_USAGE_STAGING; desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ; desc.BindFlags = 0; } D3D11_SUBRESOURCE_DATA subr = { data, width * (UINT)texel_size, width * height * (UINT)texel_size, }; ID3D11Texture2D *ret = nullptr; HRESULT hr = m_device->CreateTexture2D(&desc, data ? &subr : nullptr, &ret); if (FAILED(hr)) { return TranslateReturnCode(hr); } *dst_tex = ret; return Result::OK; }
Result GraphicsInterfaceD3D11::createBuffer(void **dst_buf, size_t size, BufferType type, const void *data, ResourceFlags flags) { D3D11_BUFFER_DESC desc = { 0 }; desc.ByteWidth = (UINT)size; desc.Usage = D3D11_USAGE_DEFAULT; switch (type) { case BufferType::Index: desc.BindFlags = D3D11_BIND_INDEX_BUFFER; break; case BufferType::Vertex: desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; break; case BufferType::Constant: desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; break; case BufferType::Compute: desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; break; } desc.CPUAccessFlags = 0; if (flags & ResourceFlags::CPU_Write) { desc.Usage = D3D11_USAGE_DYNAMIC; desc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; } if (flags & ResourceFlags::CPU_Read) { desc.Usage = D3D11_USAGE_STAGING; desc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ; desc.BindFlags = 0; } D3D11_SUBRESOURCE_DATA subr = { data, (UINT)size, 1, }; ID3D11Buffer *ret = nullptr; HRESULT hr = m_device->CreateBuffer(&desc, data ? &subr : nullptr, &ret); if (FAILED(hr)) { return TranslateReturnCode(hr); } *dst_buf = ret; return Result::OK; }
/* The send embedded callback * return : nb bytes sent, or error */ int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) { WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; int sd = dtlsCtx->fd; int sent; int len = sz; int err; WOLFSSL_ENTER("EmbedSendTo()"); sent = (int)SENDTO_FUNCTION(sd, &buf[sz - len], len, ssl->wflags, (const struct sockaddr*)dtlsCtx->peer.sa, dtlsCtx->peer.sz); sent = TranslateReturnCode(sent, sd); if (sent < 0) { err = LastError(); WOLFSSL_MSG("Embed Send To error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { WOLFSSL_MSG(" Would Block"); return WOLFSSL_CBIO_ERR_WANT_WRITE; } else if (err == SOCKET_ECONNRESET) { WOLFSSL_MSG(" Connection reset"); return WOLFSSL_CBIO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { WOLFSSL_MSG(" Socket interrupted"); return WOLFSSL_CBIO_ERR_ISR; } else if (err == SOCKET_EPIPE) { WOLFSSL_MSG(" Socket EPIPE"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } else { WOLFSSL_MSG(" General error"); return WOLFSSL_CBIO_ERR_GENERAL; } } return sent; }
/* The send embedded callback * return : nb bytes sent, or error */ int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) { int sd = *(int*)ctx; int sent; int len = sz; int err; sent = (int)SEND_FUNCTION(sd, &buf[sz - len], len, ssl->wflags); sent = TranslateReturnCode(sent, sd); if (sent < 0) { err = LastError(); WOLFSSL_MSG("Embed Send error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { WOLFSSL_MSG(" Would Block"); return WOLFSSL_CBIO_ERR_WANT_WRITE; } else if (err == SOCKET_ECONNRESET) { WOLFSSL_MSG(" Connection reset"); return WOLFSSL_CBIO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { WOLFSSL_MSG(" Socket interrupted"); return WOLFSSL_CBIO_ERR_ISR; } else if (err == SOCKET_EPIPE) { WOLFSSL_MSG(" Socket EPIPE"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } else { WOLFSSL_MSG(" General error"); return WOLFSSL_CBIO_ERR_GENERAL; } } return sent; }
Result GraphicsInterfaceD3D11::writeTexture2D(void *dst_tex_, int width, int height, TextureFormat format, const void *src, size_t write_size) { if (write_size == 0) { return Result::OK; } if (!dst_tex_ || !src) { return Result::InvalidParameter; } auto *dst_tex = (ID3D11Texture2D*)dst_tex_; auto proc_write = [this](ID3D11Texture2D *tex, int width, int height, TextureFormat format, const void *src, size_t write_size) -> HRESULT { D3D11_MAPPED_SUBRESOURCE mapped = { 0 }; auto hr = m_context->Map(tex, 0, D3D11_MAP_WRITE, 0, &mapped); if (FAILED(hr)) { return hr; } auto *dst_pixels = (char*)mapped.pData; auto *src_pixels = (const char*)src; int dst_pitch = mapped.RowPitch; int src_pitch = width * GetTexelSize(format); int num_rows = std::min<int>(height, (int)ceildiv<size_t>(write_size, src_pitch)); CopyRegion(dst_pixels, dst_pitch, src_pixels, src_pitch, num_rows); m_context->Unmap(tex, 0); return S_OK; }; // try direct access auto hr = proc_write(dst_tex, width, height, format, src, write_size); if (SUCCEEDED(hr)) { return Result::OK; } // try copy-via-staging auto staging = createStagingTexture(width, height, format, StagingFlag::Upload); hr = proc_write(staging.Get(), width, height, format, src, write_size); m_context->CopyResource(dst_tex, staging.Get()); return TranslateReturnCode(hr); }
Result GraphicsInterfaceD3D11::readTexture2D(void *dst, size_t read_size, void *src_tex_, int width, int height, TextureFormat format) { if (read_size == 0) { return Result::OK; } if (!dst || !src_tex_) { return Result::InvalidParameter; } auto *src_tex = (ID3D11Texture2D*)src_tex_; auto proc_read = [this](void *dst, size_t dst_size, ID3D11Texture2D *tex, int width, int height, TextureFormat format) -> HRESULT { D3D11_MAPPED_SUBRESOURCE mapped = { 0 }; auto hr = m_context->Map(tex, 0, D3D11_MAP_READ, 0, &mapped); if (FAILED(hr)) { return hr; } auto *dst_pixels = (char*)dst; auto *src_pixels = (const char*)mapped.pData; int dst_pitch = width * GetTexelSize(format); int src_pitch = mapped.RowPitch; int num_rows = std::min<int>(height, (int)ceildiv<size_t>(dst_size, dst_pitch)); CopyRegion(dst_pixels, dst_pitch, src_pixels, src_pitch, num_rows); m_context->Unmap(tex, 0); return S_OK; }; // try direct access auto hr = proc_read(dst, read_size, src_tex, width, height, format); if (SUCCEEDED(hr)) { return Result::OK; } // try copy-via-staging auto staging = createStagingTexture(width, height, format, StagingFlag::Readback); m_context->CopyResource(staging.Get(), src_tex); sync(); // Map() doesn't wait completion of above CopyResource(). manual synchronization is required. hr = proc_read(dst, read_size, staging.Get(), width, height, format); return TranslateReturnCode(hr); }
/* The receive embedded callback * return : nb bytes read, or error */ int EmbedReceiveFrom(CYASSL *ssl, char *buf, int sz, void *ctx) { CYASSL_DTLS_CTX* dtlsCtx = (CYASSL_DTLS_CTX*)ctx; int recvd; int err; int sd = dtlsCtx->fd; int dtls_timeout = CyaSSL_dtls_get_current_timeout(ssl); struct sockaddr_storage peer; XSOCKLENT peerSz = sizeof(peer); CYASSL_ENTER("EmbedReceiveFrom()"); if (!CyaSSL_get_using_nonblock(ssl) && dtls_timeout != 0) { #ifdef USE_WINDOWS_API DWORD timeout = dtls_timeout * 1000; #else struct timeval timeout; XMEMSET(&timeout, 0, sizeof(timeout)); timeout.tv_sec = dtls_timeout; #endif if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) != 0) { CYASSL_MSG("setsockopt rcvtimeo failed"); } } recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags, (struct sockaddr*)&peer, &peerSz); recvd = TranslateReturnCode(recvd, sd); if (recvd < 0) { err = LastError(); CYASSL_MSG("Embed Receive From error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { if (CyaSSL_get_using_nonblock(ssl)) { CYASSL_MSG(" Would block"); return CYASSL_CBIO_ERR_WANT_READ; } else { CYASSL_MSG(" Socket timeout"); return CYASSL_CBIO_ERR_TIMEOUT; } } else if (err == SOCKET_ECONNRESET) { CYASSL_MSG(" Connection reset"); return CYASSL_CBIO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { CYASSL_MSG(" Socket interrupted"); return CYASSL_CBIO_ERR_ISR; } else if (err == SOCKET_ECONNREFUSED) { CYASSL_MSG(" Connection refused"); return CYASSL_CBIO_ERR_WANT_READ; } else { CYASSL_MSG(" General error"); return CYASSL_CBIO_ERR_GENERAL; } } else { if (dtlsCtx->peer.sz > 0 && peerSz != (XSOCKLENT)dtlsCtx->peer.sz && memcmp(&peer, dtlsCtx->peer.sa, peerSz) != 0) { CYASSL_MSG(" Ignored packet from invalid peer"); return CYASSL_CBIO_ERR_WANT_READ; } } return recvd; }
/* The receive embedded callback * return : nb bytes read, or error */ int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx) { int recvd; int err; int sd = *(int*)ctx; #ifdef CYASSL_DTLS { int dtls_timeout = CyaSSL_dtls_get_current_timeout(ssl); if (CyaSSL_dtls(ssl) && !CyaSSL_get_using_nonblock(ssl) && dtls_timeout != 0) { #ifdef USE_WINDOWS_API DWORD timeout = dtls_timeout * 1000; #else struct timeval timeout; XMEMSET(&timeout, 0, sizeof(timeout)); timeout.tv_sec = dtls_timeout; #endif if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) != 0) { CYASSL_MSG("setsockopt rcvtimeo failed"); } } } #endif recvd = (int)RECV_FUNCTION(sd, buf, sz, ssl->rflags); recvd = TranslateReturnCode(recvd, sd); if (recvd < 0) { err = LastError(); CYASSL_MSG("Embed Receive error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { if (!CyaSSL_dtls(ssl) || CyaSSL_get_using_nonblock(ssl)) { CYASSL_MSG(" Would block"); return CYASSL_CBIO_ERR_WANT_READ; } else { CYASSL_MSG(" Socket timeout"); return CYASSL_CBIO_ERR_TIMEOUT; } } else if (err == SOCKET_ECONNRESET) { CYASSL_MSG(" Connection reset"); return CYASSL_CBIO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { CYASSL_MSG(" Socket interrupted"); return CYASSL_CBIO_ERR_ISR; } else if (err == SOCKET_ECONNREFUSED) { CYASSL_MSG(" Connection refused"); return CYASSL_CBIO_ERR_WANT_READ; } else if (err == SOCKET_ECONNABORTED) { CYASSL_MSG(" Connection aborted"); return CYASSL_CBIO_ERR_CONN_CLOSE; } else { CYASSL_MSG(" General error"); return CYASSL_CBIO_ERR_GENERAL; } } else if (recvd == 0) { CYASSL_MSG("Embed receive connection closed"); return CYASSL_CBIO_ERR_CONN_CLOSE; } return recvd; }